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

MongoDB Query: Aggregate อาร์เรย์ซ้อน (Nested Array)


การประมวลผลอาร์เรย์ซ้อนหลายชั้นด้วย Aggregation Pipeline

ใช้ $addFields, $map, $let, $arrayElemAt, $cond เพื่อแปลงและกรองข้อมูลในอาร์เรย์ซ้อนหลายระดับ

ตัวอย่างข้อมูล (3 ระดับ)

> db.demo441.insertOne({
  "Name": "David", "Age": 21,
  "details": [{
    "id": 1, "CountryName": "US",
    "details1": [
      { "SubjectName": "MySQL", "Score": 56 },
      { "SubjectName": "MongoDB", "Score": 78 }
    ]
  }]
});

Query Aggregate อาร์เรย์ซ้อน

> db.demo441.aggregate([{
  $addFields: {
    ResultOfDetails: {
      $map: {
        input: "$details",
        as: "output",
        in: {
          id: "$$output.id",
          CountryName: "$$output.CountryName",
          details1: {
            $let: {
              vars: {
                last: { $arrayElemAt: ["$$output.details1", -1] }
              },
              in: {
                $cond: [
                  { $eq: ["$$last.Score", 78] },
                  ["$$last"],
                  []
                ]
              }
            }
          }
        }
      }
    }
  }
}]).pretty();

ผลลัพธ์

{
  "_id": ObjectId(...), "Name": "David", "Age": 21,
  "details": [{ "id": 1, "CountryName": "US", "details1": [{ "SubjectName": "MySQL", "Score": 56 }, { "SubjectName": "MongoDB", "Score": 78 }] }],
  "ResultOfDetails": [{ "id": 1, "CountryName": "US", "details1": [{ "SubjectName": "MongoDB", "Score": 78 }] }]
}

คำอธิบาย Operator สำคัญ

  • $map - วนลูปแปลงแต่ละอิลิเมนต์ในอาร์เรย์
  • $let - กำหนดตัวแปรชั่วคราว (vars) เพื่อใช้ซ้ำ
  • $arrayElemAt: [..., -1] - ดึงอิลิเมนต์สุดท้ายของอาร์เรย์
  • $cond - เงื่อนไข if-then-else

การประยุกต์

รูปแบบนี้เหมาะสำหรับ: การกรองรายวิชาที่ผ่าน/ไม่ผ่าน, ดึงข้อมูลล่าสุดในแต่ละกลุ่ม, แปลงโครงสร้างข้อมูลซ้อนซับซ้อน