ใช้ $group รวมตาม Id1 แล้ว $match กรองกลุ่มที่มี count > 1 และ docs มี Id2 ครบทุกค่าที่ต้องการ (Intersection)
ตัวอย่างข้อมูลทดสอบ
> db.demo393.insertOne({"Id1":"1","Name":"Chris","Id2":"100"});
> db.demo393.insertOne({"Id1":"1","Name":"Chris","Id2":"101"});
> db.demo393.insertOne({"Id1":"3","Name":"Chris","Id2":"100"});
> db.demo393.insertOne({"Id1":"3","Name":"Mike","Id2":"101"});
แสดงข้อมูลทั้งหมด
> db.demo393.find();
{
"_id" : ObjectId("5e5e6dd522064be7ab44e804"), "Id1" : "1", "Name" : "Chris", "Id2" : "100"
}
{
"_id" : ObjectId("5e5e6dd522064be7ab44e805"), "Id1" : "1", "Name" : "Chris", "Id2" : "101"
}
{
"_id" : ObjectId("5e5e6dd522064be7ab44e806"), "Id1" : "3", "Name" : "Chris", "Id2" : "100"
}
{
"_id" : ObjectId("5e5e6dd522064be7ab44e807"), "Id1" : "3", "Name" : "Mike", "Id2" : "101"
}
คำสั่ง Aggregation หา Id1 ที่ Name=Chris และมี Id2 ครบทั้ง 100 และ 101
> db.demo393.aggregate([
{"$match": {"Name": "Chris"}},
{"$group": {
"_id": "$Id1",
"docs": {"$push": "$$ROOT"},
"count": {"$sum": 1}
}},
{"$match": {
"count": {"$gt": 1},
"docs": {
"$all": [
{"$elemMatch": {"Id2": "100"}},
{"$elemMatch": {"Id2": "101"}}
]
}
}}
])
ผลลัพธ์ (ได้เฉพาะ Id1 = "1" ที่มี Id2 ครบทั้ง 100, 101)
{
"_id" : "1",
"docs" : [
{"_id" : ObjectId("5e5e6dd522064be7ab44e804"), "Id1" : "1", "Name" : "Chris", "Id2" : "100"},
{"_id" : ObjectId("5e5e6dd522064be7ab44e805"), "Id1" : "1", "Name" : "Chris", "Id2" : "101"}
],
"count" : 2
}
คำอธิบาย:
$matchกรอง Name = Chris ก่อน (ลดข้อมูล)$groupรวมตาม Id1 สะสม docs ทั้งหมดและนับ count$matchครั้งที่ 2: count > 1 (มีหลายรายการ) และ docs มี $elemMatch Id2=100 และ Id2=101 ทั้งคู่- Id1="3" มีแค่ Id2="100" จึงไม่ผ่าน