Để xóa document trùng lặp dựa trên kết hợp 2 trường, dùng pipeline aggregate với $group, $sort, $replaceRoot và $out để ghi đè collection.
Dữ liệu có trùng lặp
> db.demo108.insertOne({"Value1":23,"Value2":24});
{ "acknowledged" : true, "insertedId" : ObjectId("5e2ee3e49fd5fd66da214477") }
> db.demo108.insertOne({"Value1":23,"Value2":25});
{ "acknowledged" : true, "insertedId" : ObjectId("5e2ee3f29fd5fd66da214478") }
> db.demo108.insertOne({"Value1":23,"Value2":24});
{ "acknowledged" : true, "insertedId" : ObjectId("5e2ee3f59fd5fd66da214479") }
Pipeline xóa trùng lặp
> db.demo108.aggregate([
{ "$sort": { "_id": 1 } },
{ "$group": {
"_id": { "Value1": "$Value1", "Value2": "$Value2" },
"doc": { "$first": "$$ROOT" }
}},
{ "$replaceRoot": { "newRoot": "$doc" } },
{ "$out": "demo108" }
]);
Kết quả (chỉ còn 2 document unique)
{ "_id" : ObjectId("5e2ee3f29fd5fd66da214478"), "Value1" : 23, "Value2" : 25 }
{ "_id" : ObjectId("5e2ee3e49fd5fd66da214477"), "Value1" : 23, "Value2" : 24 }
Giải thích pipeline:
$sort: Sắp xếp theo _id để giữ document đầu tiên (cũ nhất) khi trùng$group: Nhóm theo cặp (Value1, Value2), lấy$first(document đầu tiên sau sort)$replaceRoot: Phục hồi cấu trúc document gốc từ fielddoc$out: Ghi kết quả đè lên collection gốc (xóa data cũ)
Cảnh báo: $out sẽ xóa toàn bộ collection và thay bằng kết quả aggregate. Hãy backup trước khi chạy production.