Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MongoDB

จับคู่เอกสารที่มีค่าตรงกันทั้งหมดในฟิลด์เฉพาะด้วย MongoDB Aggregation

ใช้ $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
}

คำอธิบาย:

  1. $match กรอง Name = Chris ก่อน (ลดข้อมูล)
  2. $group รวมตาม Id1 สะสม docs ทั้งหมดและนับ count
  3. $match ครั้งที่ 2: count > 1 (มีหลายรายการ) และ docs มี $elemMatch Id2=100 และ Id2=101 ทั้งคู่
  4. Id1="3" มีแค่ Id2="100" จึงไม่ผ่าน