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

การรวมอาร์เรย์ซ้อนหลายชั้น (Deep Sub-lists) ใน MongoDB ด้วย Aggregate และ $unwind

ใช้ aggregate() ร่วมกับ $unwind หลายขั้นตอน เพื่อ "แบน" (flatten) อาร์เรย์ซ้อนหลายชั้น แล้วจึงกรอง/เรียงลำดับ/จำกัดจำนวนผลลัพธ์

ตัวอย่างข้อมูลโครงสร้างซ้อนหลายชั้น

> db.demo70.insertOne({
    "first": [
      {
        "details": {
          "second": [
            { "StudentDetails": { "Score": 10 } },
            { "StudentDetails": { "Score": 20 } },
            { "StudentDetails": { "Score": 30 } }
          ]
        }
      },
      {
        "details": {
          "second": [
            { "StudentDetails": { "Score": 11 } },
            { "StudentDetails": { "Score": 18 } },
            { "StudentDetails": { "Score": 29 } }
          ]
        }
      }
    ]
  });
{ "acknowledged": true, "insertedId": ObjectId("5e29ad4d0912fae76b13d76d") }

แสดงโครงสร้างข้อมูล

> db.demo70.find().pretty();

ผลลัพธ์ (โครงสร้างซ้อน 3 ชั้น: first → details.second → StudentDetails.Score)

{
  "_id": ObjectId("5e29ad4d0912fae76b13d76d"),
  "first": [
    {
      "details": {
        "second": [
          { "StudentDetails": { "Score": 10 } },
          { "StudentDetails": { "Score": 20 } },
          { "StudentDetails": { "Score": 30 } }
        ]
      }
    },
    {
      "details": {
        "second": [
          { "StudentDetails": { "Score": 11 } },
          { "StudentDetails": { "Score": 18 } },
          { "StudentDetails": { "Score": 29 } }
        ]
      }
    }
  ]
}

Aggregate Pipeline: $unwind 2 ครั้ง + เรียงลำดับ + จำกัด 3 อันดับแรก

> db.demo70.aggregate([
    { $unwind: "$first" },
    { $unwind: "$first.details.second" },
    { $sort: { "first.details.second.StudentDetails.Score": -1 } },
    { $limit: 3 },
    { $replaceRoot: { newRoot: "$first.details.second.StudentDetails" } },
    { $sort: { "Score": 1 } }
  ]);

ผลลัพธ์ (คะแนนสูงสุด 3 อันดับ แล้วเรียงน้อยไปมาก)

{ "Score": 20 }
{ "Score": 29 }
{ "Score": 30 }

คำอธิบาย Pipeline:

  1. $unwind: "$first" - แยกอาร์เรย์ first ออกเป็นเอกสารแยกกัน
  2. $unwind: "$first.details.second" - แยกอาร์เรย์ second ออกเป็นเอกสารแยกกัน
  3. $sort - เรียงคะแนนจากมากไปน้อย
  4. $limit: 3 - เอาแค่ 3 อันดับแรก
  5. $replaceRoot - ยกฟิลด์ StudentDetails ขึ้นมาเป็นรากเอกสาร
  6. $sort: { "Score": 1 } - เรียงผลลัพธ์สุดท้ายจากน้อยไปมาก