Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MongoDB

Nhóm giá trị theo trường khác trong MongoDB Aggregation

Sử dụng $group kết hợp $addToSet và $reduce với $concatArrays để gom các giá trị mảng từ nhiều tài liệu theo nhóm.

Tạo collection:

> db.demo374.insertOne({
  "Name" : "Chris",
  "HobbyDetails" : [ "Reading Book", "Playing Football" ],
  "CountryName" : "US"
});
{ "acknowledged" : true, "insertedId" : ObjectId("5e5a04402ae06a1609a00b04") }
> db.demo374.insertOne({
  "Name" : "Chris",
  "HobbyDetails" : [ "Browsing Internet", "Playing Football" ],
  "CountryName" : "US"
});
{ "acknowledged" : true, "insertedId" : ObjectId("5e5a04402ae06a1609a00b05") }

Xem dữ liệu (2 tài liệu cùng Name=Chris, Country=US):

> db.demo374.find();
{ "_id" : ObjectId("5e5a04402ae06a1609a00b04"), "Name" : "Chris", "HobbyDetails" : [ "Reading Book", "Playing Football" ], "CountryName" : "US" }
{ "_id" : ObjectId("5e5a04402ae06a1609a00b05"), "Name" : "Chris", "HobbyDetails" : [ "Browsing Internet", "Playing Football" ], "CountryName" : "US" }

Aggregation nhóm theo Name, gom HobbyDetails:

> db.demo374.aggregate([
  {$match : { "CountryName" : "US"}},
  {$group : {"_id" : "$Name", "HobbyDetails" : {$addToSet : "$HobbyDetails"}}},
  {$project : {"_id" : 0, "Name" : "$_id", "HobbyDetails" : {$reduce : {input : "$HobbyDetails", initialValue : [], in: { $concatArrays : ["$$value", "$$this"] }}}}}
]).pretty()

Kết quả (mảng phẳng, có trùng lặp "Playing Football"):

Giải thích:

  • $match: lọc Country=US
  • $group với $addToSet: gom mảng HobbyDetails thành mảng các mảng (loại trùng lặp mảng hoàn toàn)
  • $reduce + $concatArrays: làm phẳng (flatten) mảng các mảng thành một mảng

Lưu ý: $addToSet ở đây so sánh cả mảng, nên 2 mảng khác nhau vẫn được giữ cả hai. Để unique từng phần tử, cần $unwind trước khi $addToSet.