Để nhóm theo nhiều trường và đếm các giá trị trùng lặp, hãy sử dụng pipeline aggregate kết hợp với toán tử $cond. Toán tử $cond đánh giá biểu thức boolean để trả về một trong hai biểu thức chỉ định.
Tạo collection với tài liệu mẫu:
> db.demo536.insertOne({"Name1":"Chris","Name2":"David"});
{ "acknowledged" : true, "insertedId" : ObjectId("5e8c843eef4dcbee04fbbc01") }
> db.demo536.insertOne({"Name1":"David","Name2":"Chris"});
{ "acknowledged" : true, "insertedId" : ObjectId("5e8c843fef4dcbee04fbbc02") }
> db.demo536.insertOne({"Name1":"Bob","Name2":"Sam"});
{ "acknowledged" : true, "insertedId" : ObjectId("5e8c843fef4dcbee04fbbc03") }
> db.demo536.insertOne({"Name1":"Chris","Name2":"David"});
{ "acknowledged" : true, "insertedId" : ObjectId("5e8c843fef4dcbee04fbbc04") }
Hiển thị tất cả tài liệu:
> db.demo536.find();
Kết quả:
{ "_id" : ObjectId("5e8c843eef4dcbee04fbbc01"), "Name1" : "Chris", "Name2" : "David" }
{ "_id" : ObjectId("5e8c843fef4dcbee04fbbc02"), "Name1" : "David", "Name2" : "Chris" }
{ "_id" : ObjectId("5e8c843fef4dcbee04fbbc03"), "Name1" : "Bob", "Name2" : "Sam" }
{ "_id" : ObjectId("5e8c843fef4dcbee04fbbc04"), "Name1" : "Chris", "Name2" : "David" }
Truy vấn aggregate để nhóm theo cặp tên (bất kể thứ tự) và đếm:
> db.demo536.aggregate([
... {
... $project:
... {
... FirstName1:
... {
... $cond: { if: { $gte: [ "$Name1", "$Name2" ] }, then: "$Name2", else: "$Name1" }
... },
... FirstName2:
... {
... $cond: { if: { $lt: [ "$Name1", "$Name2" ] }, then: "$Name2", else: "$Name1" }
... }
... }
... },
... {
... $group:
... {
... _id:
... {
... Name1: "$FirstName1",
... Name2: "$FirstName2"
... },
... count: { $sum: 1}
... }
... }
... ])
Kết quả (cặp "Chris", "David" xuất hiện 3 lần do có 2 bản ghi thứ tự ngược và 1 bản ghi trùng):
{ "_id" : { "Name1" : "Bob", "Name2" : "Sam" }, "count" : 1 }
{ "_id" : { "Name1" : "Chris", "Name2" : "David" }, "count" : 3 }