ใช้ $project ร่วม $filter สำหรับกรอง Sub-document
เมื่อต้องการคืนเอกสารเต็มรูปแบบ แต่เฉพาะ sub-document ในอาร์เรย์ที่ผ่านเงื่อนไข ให้ใช้ $project พร้อม $filter ใน aggregation pipeline
ตัวอย่างข้อมูล
> db.demo457.insertOne({ _id: 101, details: [{ ProductName: "Product-1", ProductPrice: 90 }, { ProductName: "Product-2", ProductPrice: 190 }] });
> db.demo457.insertOne({ _id: 102, details: [{ ProductName: "Product-3", ProductPrice: 150 }, { ProductName: "Product-4", ProductPrice: 360 }] });
Query กรอง ProductPrice >= 170
> db.demo457.aggregate([
{ $project: {
details: {
$filter: {
input: "$details",
as: "output",
cond: { $gte: ["$$output.ProductPrice", 170] }
}
}
}}
]);
ผลลัพธ์
{ "_id": 101, "details": [{ "ProductName": "Product-2", "ProductPrice": 190 }] }
{ "_id": 102, "details": [{ "ProductName": "Product-4", "ProductPrice": 360 }] }
คำอธิบาย
- input: "$details" - อาร์เรย์ต้นทาง
- as: "output" - ตัวแปรแทนแต่ละอิลิเมนต์ (ใช้ด้วย $$output)
- cond - เงื่อนไขการกรอง (true = เก็บ, false = ตัดทิ้ง)
- ฟิลด์อื่นๆ (เช่น _id) จะถูกเก็บไว้อัตโนมัติหากไม่ระบุใน $project
Operator เพิ่มเติมใน $filter
$filter- กรองอาร์เรย์ (MongoDB 3.2+)$map- แปลงแต่ละอิลิเมนต์$reduce- รวมอาร์เรย์เป็นค่าเดียว$zip- รวมอาร์เรย์หลายตัวตาม index
กรณีต้องการเก็บฟิลด์อื่นด้วย
{ $project: { _id: 1, details: { $filter: ... }, otherField: 1 } }