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$groupvớ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.