Mongodb Aggregate Complex Document พร้อม Nested Lookups

Aug 19 2020

ฉันมีคอลเล็กชันเหล่านี้:

ไซต์

{
  _id: ObjectId("5acdb8f65ea63a27c1facf86"),
  TemplateId: ObjectId("sdfsdfs34234234sdf"),
}

เทมเพลต

{
  _id: ObjectId("sdfsdfs34234234sdf"),
  Type: "Site",
  Name: "Site 1",
  Sections:[{
     id: ObjectId("8asdf89asd8f9sdf"),
     Header: "Header1",
     FieldItems: [
           {
            FieldId: ObjectId("jsd32423423423"),
            x: 1,
            y: 0
           },
           {
            FieldId: ObjectId("2342sdffafdasdfdfs"),
            x: 1,
            y: 1
           }
          ]
        },
       (...more sections...)
     ]
}

ฟิลด์

{
  _id: ObjectId("jsd32423423423"),
  Type: "Phone",
  Name: "Phone_Test"
},
{
  _id: ObjectId("2342sdffafdasdfdfs"),
  Type: "Numeric",
  Name: "Number_Test"
}
            

ฉันยังใหม่กับ MongoDB แต่ต้องใช้เวลาสองสามวันในการอ่านคำถามและคำตอบตลอดจนเอกสารประกอบ ฉันใช้ MongoDB 4.2.6 ฉันกำลังพยายามส่งคืนผลลัพธ์ในรูปแบบเช่นนี้:

{
  id: ObjectId("5acdb8f65ea63a27c1facf86"),
  TemplateId: ObjectId("sdfsdfs34234234sdf"),
  Template: {
   id: ObjectId("sdfsdfs34234234sdf"),
   Type: "Site",
   Sections:[{
     id: ObjectId("8asdf89asd8f9sdf"),
     Header: "Header1",
     FieldItems: [
        {
          FieldId: ObjectId("jsd32423423423"),
          x: 1,
          y: 0,
          Field: {
              _id: ObjectId("jsd32423423423"),
              Type: "Phone",
              Name: "Phone_Test"
           }
        }, (...)]
      }]
}
  

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

db.getCollection("AppSites").aggregate(
[
    { 
        "$lookup" : { "from" : "AppTemplates", "let": {"template_id": "$TemplateId"},
            "pipeline": [
                { "$match": { "$expr": { "$eq" : ["$_id", "$$template_id"] } } }, { "$unwind": "$Sections"}, { "$unwind": "$Sections.FieldItems"}, { "$lookup": {
                        "from": "AppFields",
                        "let": {"field_id": "$Sections.FieldItems.FieldId"}, "pipeline": [ { "$match": { "$expr": { "$eq": ["$_id", "$$field_id"] } } }
                        ],
                        "as": "Sections.FieldItems.Field"
                    }
                }
            ],
            "as" : "Templates"
        }
    }
]
);

คำตอบ

1 varman Aug 19 2020 at 00:21

คุณทำ$unwindสองครั้งแล้วดังนั้นคุณต้องใช้สอง$groupครั้ง

{
  $group: { _id: { secId: "$_id",
      fId: "$Sections.id" }, Type: { $first: "$Type" }, Name: { $first: "$Name" }, Header: { $first: "$Sections.Header" }, fieldItems: { $push: "$Sections.FieldItems" } } }, { $group: {
    _id: "$_id.secId", Type: { $first: "$Type" }, Name: { $first: "$Name" }, Sections: { $push: {
        id: "$_id.fId", Header: "$Header",
        fieldItems: "$fieldItems"
      }
    }
  }
}
  1. กลุ่มแรก - เพื่อจัดกลุ่มวัตถุลูก แต่ต้องตั้งค่าType, Name และ Headerเป็นพาเรนต์และอาร์เรย์ลูกตามลำดับ
  2. กลุ่มที่สอง - เพื่อจัดกลุ่มออบเจ็กต์หลัก เราได้รับทุกฟิลด์แบบสแตนด์อโลนในขณะที่จัดกลุ่มเด็ก ที่นี่เราต้องตั้งค่าใน oreders ที่ถูกต้อง

สนามเด็กเล่น Mongoทำงาน

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