ใช้ $elemMatch สำหรับ Match หลายเงื่อนไขในอิลิเมนต์เดียว
operator $elemMatch ใช้จับคู่เอกสารที่มีอิลิเมนต์ในอาร์เรย์ตรงตาม เงื่อนไขหลายอย่างพร้อมกัน ในอิลิเมนต์เดียวกัน
ตัวอย่างข้อมูล
> db.demo453.insertOne({ _id: 101, details: [{ Name: "David", Marks: 60 }, { Name: "Mike", Marks: 55 }] });
> db.demo453.insertOne({ _id: 102, details: [{ Name: "Bob", Marks: 80 }, { Name: "Sam", Marks: 78 }] });
> db.demo453.insertOne({ _id: 103, details: [{ Name: "Carol", Marks: 67 }, { Name: "John", Marks: 79 }] });
Query หาเอกสารที่มี Marks >= 75 ในอิลิเมนต์เดียวกัน
> db.demo453.find({
details: { $elemMatch: { Marks: { $gte: 75 } } }
});
ผลลัพธ์
{ "_id": 102, "details": [{ "Name": "Bob", "Marks": 80 }, { "Name": "Sam", "Marks": 78 }] }
{ "_id": 103, "details": [{ "Name": "Carol", "Marks": 67 }, { "Name": "John", "Marks": 79 }] }
ความแตกต่างสำคัญ
| Query | ผลลัพธ์ |
|---|---|
| { "details.Marks": { $gte: 75 } } | คืน _id 102, 103 (เพราะ 103 มี John=79 แม้ Carol=67) |
| { details: { $elemMatch: { Marks: { $gte: 75 } } } } | คืน _id 102, 103 (เหมือนกันในกรณีนี้ เพราะเงื่อนไขเดียว) |
| { details: { $elemMatch: { Name: "Bob", Marks: { $gte: 75 } } } } | คืน _id 102 เท่านั้น (Bob และ Marks>=75 ต้องอยู่ในอิลิเมนต์เดียวกัน) |
| { "details.Name": "Bob", "details.Marks": { $gte: 75 } } | คืน _id 102, 103 (Name=Bob ใน 102, Marks>=79 ใน 103 - อิลิเมนต์ต่างกันได้) |
เมื่อไหร่ควรใช้ $elemMatch
- ต้องการ match หลายฟิลด์ใน อิลิเมนต์เดียวกัน
- อาร์เรย์ของออบเจ็กต์ (array of objects)
- ต้องการความแม่นยำในเงื่อนไข