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

MongoDB Aggregation: Group và loại bỏ giá trị trùng lặp trong mảng

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:

  1. $unwind: "$Names": Phân rã mảng → 4 document cho _id 101, 2 document cho _id 102
  2. $group với $addToSet: Gom lại theo _id, thu thập Names vào **Set** (tự động loại trùng)
  3. $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.