Sử dụng aggregate() với $unwind và $group + $addToSet để gom nhóm và loại trùng lặp trong mảng.
Tạo collection với mảng có giá trị trùng
> db.demo649.insertOne({ _id: 101, Names: ["John", "Bob", "Bob", "Robert"], CountryName: "US" });
> db.demo649.insertOne({ _id: 102, Names: ["John", "Robert"], CountryName: "UK" });
Hiển thị dữ liệu gốc
> db.demo649.find();
Kết quả:
_id:101 Names:[John, Bob, Bob, Robert] Country:US _id:102 Names:[John, Robert] Country:UK
Aggregate loại trùng lặp trong mảng Names
> db.demo649.aggregate([
{ $unwind: "$Names" },
{
$group: {
_id: "$_id",
Names: { $addToSet: "$Names" },
CountryName: { $first: "$CountryName" }
}
}
])
Kết quả (mảng Names không còn trùng):
{
"_id" : 102, "Names" : [ "Robert", "John" ], "CountryName" : "UK"
}
{
"_id" : 101, "Names" : [ "Robert", "Bob", "John" ], "CountryName" : "US"
}
Giải thích:
$unwind: "$Names": Phân rã mảng → 4 document cho _id 101, 2 document cho _id 102$groupvới$addToSet: Gom lại theo_id, thu thậpNamesvào **Set** (tự động loại trùng)$first: "$CountryName": Lấy giá trị CountryName đầu tiên (cùng giá trị cho tất cả document sau unwind)
So sánh $push vs $addToSet:
$push: Thêm tất cả giá trị, **giữ trùng lặp → [John, Bob, Bob, Robert]$addToSet: Chỉ thêm nếu chưa có, **loại trùng lặp** → [John, Bob, Robert] (thứ tự không đảm bảo)
Pattern này dùng cho: deduplication, tạo danh sách tag duy nhất, distinct values per group.