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

การกรอง Sub-documents หลายชุดใน MongoDB ด้วย Aggregation Pipeline

กรอง Sub-documents หลายชุดพร้อมกันด้วย aggregate()

บทความนี้สาธิตวิธีการกรองข้อมูลจาก Sub-documents หลายชุด (multiple sub-document arrays) ในเอกสารเดียวกัน โดยใช้ Aggregation Pipeline หลายขั้นตอน: $match, $unwind, $group, $project

ขั้นตอนที่ 1: สร้าง Collection และเพิ่มข้อมูลตัวอย่าง

สร้าง collection ชื่อ demo200 ซึ่งมีอาร์เรย์ 2 ชุด คือ details1 และ details2 แต่ละชุดมีฟิลด์ isActive เพื่อระบุสถานะ

> db.demo200.insertOne({
    "Id": "101",
    "details1": [
        { "isActive": true, "SubjectName": "MySQL" },
        { "isActive": false, "SubjectName": "Java" }
    ],
    "details2": [
        { "isActive": false, "Name": "David" },
        { "isActive": true, "Name": "Mike" }
    ]
});
{ "acknowledged": true, "insertedId": ObjectId("5e3c374f03d395bdc21346e4") }

ขั้นตอนที่ 2: แสดงข้อมูลทั้งหมด

> db.demo200.find();

ผลลัพธ์:

{ "_id": ObjectId("5e3c374f03d395bdc21346e4"), "Id": "101", "details1": [
    { "isActive": true, "SubjectName": "MySQL" },
    { "isActive": false, "SubjectName": "Java" }
], "details2": [
    { "isActive": false, "Name": "David" },
    { "isActive": true, "Name": "Mike" }
] }

ขั้นตอนที่ 3: Aggregation Pipeline สำหรับกรอง Sub-documents หลายชุด

Pipeline ประกอบด้วยขั้นตอนดังนี้:

  1. $match - กรองเอกสารหลักที่มี Id: "101" และทั้ง 2 อาร์เรย์มี isActive: true อย่างน้อย 1 รายการ
  2. $unwind: "$details1" - แยกอาร์เรย์ details1
  3. $unwind: "$details2" - แยกอาร์เรย์ details2
  4. $match - กรองเฉพาะรายการที่ details1.isActive: true และ details2.isActive: true
  5. $group - รวมกลับเป็นอาร์เรย์ด้วย $addToSet
  6. $project - จัดรูปแบบเอาต์พุตสุดท้าย
> var out = [
    { "$match": { "Id": "101", "details1.isActive": true, "details2.isActive": true } },
    { "$unwind": "$details1" },
    { "$unwind": "$details2" },
    { "$match": { "details1.isActive": true, "details2.isActive": true } },
    { "$group": {
        "_id": { "_id": "$_id", "Id": "$Id" },
        "details2": { "$addToSet": "$details2" },
        "details1": { "$addToSet": "$details1" }
    }},
    { "$project": { "_id": 0, "Id": "$_id.Id", "details2": 1, "details1": 1 } }
];
> db.demo200.aggregate(out)

ผลลัพธ์ที่ได้

{ "details2": [{ "isActive": true, "Name": "Mike" }], "details1": [{ "isActive": true, "SubjectName": "MySQL" }], "Id": "101" }

สรุป: เทคนิคนี้เหมาะสำหรับกรณีที่ต้องกรองข้อมูลจากอาร์เรย์หลายชุดพร้อมกัน และต้องการผลลัพธ์ที่รวมเฉพาะรายการที่ตรงเงื่อนไขจากทุกชุด