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

MongoDB $unwind: นับจำนวนข้อมูลในอาร์เรย์ซ้อน


ใช้ $unwind แยกอาร์เรย์ แล้ว $group นับตามเงื่อนไข

Operator $unwind แยกอาร์เรย์ออกเป็นเอกสารแยกต่างหาก ทำให้สามารถประมวลผลแต่ละอิลิเมนต์ได้ แล้ว $group นับเฉพาะที่ตรงเงื่อนไข

ตัวอย่างข้อมูล (อาร์เรย์ซ้อน 2 ระดับ)

> db.demo478.insertOne({
  Details: {
    _id: 1,
    Information: [
      { Name: "Chris", Age: 21 },
      { Name: "David", Age: 23 },
      { Name: null, Age: 22 },
      { Name: null, Age: 24 }
    ]
  }
});
> db.demo478.insertOne({
  Details: {
    _id: 2,
    Information: [
      { Name: "Bob", Age: 21 },
      { Name: null, Age: 20 }
    ]
  }
});

Query $unwind และนับเฉพาะ Name ไม่เป็น null

> db.demo478.aggregate([
  { $unwind: "$Details.Information" },
  { $group: {
      _id: "$Details.Information.Age",
      count: { $sum: { $cond: [{ $gt: ["$Details.Information.Name", null] }, 1, 0] } }
  }},
  { $sort: { count: -1 } }
]);

ผลลัพธ์

{ "_id": 21, "count": 2 }
{ "_id": 23, "count": 1 }
{ "_id": 24, "count": 0 }
{ "_id": 20, "count": 0 }
{ "_id": 22, "count": 0 }

คำอธิบาย

  1. $unwind: "$Details.Information" - แยกอาร์เรย์ Information เป็นเอกสารแยกต่างหาก (6 เอกสาร)
  2. $group - จัดกลุ่มตาม Age
  3. $cond: [{ $gt: ["$Details.Information.Name", null] }, 1, 0] - นับ 1 ถ้า Name ไม่เป็น null, ไม่นับถ้าเป็น null
  4. $sort: { count: -1 } - เรียงตามจำนวนมากไปน้อย
  5. การนับแบบอื่นๆ

    // นับทั้งหมด (รวม null)
    { $group: { _id: "$Details.Information.Age", count: { $sum: 1 } } }
    
    // นับ distinct Name ต่อ Age
    { $group: { _id: "$Details.Information.Age", uniqueNames: { $addToSet: "$Details.Information.Name" } } },
    { $project: { _id: 1, count: { $size: "$uniqueNames" } } }
    
    // ใช้ $facet นับหลายอย่างพร้อมกัน (MongoDB 3.4+)
    { $facet: {
        total: [{ $count: "total" }],
        nonNull: [{ $match: { "Details.Information.Name": { $ne: null } } }, { $count: "nonNull" }]
    } }