ใช้ $addFields ร่วม $filter ใน aggregation เพื่อกรอง sub-documents และเก็บเฉพาะที่ตรงเงื่อนไข สร้างคอลเลกชันตัวอย่าง:
> db.demo334.insertOne({
"Name": "Chris",
"Age": 21,
"details": [
{"Subject": "MySQL", "Score": 78},
{"Subject": "MongoDB", "Score": 45}
]
});
{ "acknowledged" : true, "insertedId" : ObjectId("5e52241bf8647eb59e562090") }
แสดงข้อมูล:
> db.demo334.find().pretty();
คิวรีกรองเฉพาะรายการที่ Score >= 70:
> db.demo334.aggregate([
{ $addFields: {
details: {$filter: {
input: '$details',
as: 'out',
cond: {$gte: ['$$out.Score', 70]}
}}
}}
])
ผลลัพธ์ (เหลือเฉพาะ MySQL ที่ Score 78):
{ "_id" : ObjectId("5e52241bf8647eb59e562090"), "Name" : "Chris", "Age" : 21, "details" : [ { "Subject" : "MySQL", "Score" : 78 } ] }
คำอธิบาย
$addFields: เพิ่ม/แก้ไขฟิลด์ในเอกสาร (เหมือน $set แต่ใน aggregation)$filter: กรองสมาชิกในอาร์เรย์ตามเงื่อนไขcond$$out: ตัวแปรอ้างอิงสมาชิกปัจจุบันในอาร์เรย์$gte: Greater than or equal (>=)
กรณีศึกษา
เทคนิคนี้เหมาะสำหรับการ "filter sub-documents" ในเอกสารหลัก โดยไม่ต้อง $unwind แล้ว $group กลับ (ซับซ้อนและช้ากว่า)