ใช้ Dot Notation ใน find() สำหรับ Query อาร์เรย์ของออบเจ็กต์
MongoDB รองรับการ query เข้าถึงฟิลด์ภายในออบเจ็กต์ที่อยู่ในอาร์เรย์ได้โดยตรงด้วย dot notation
ตัวอย่างข้อมูล
> db.demo465.insertOne({
id: 101,
details: [
{ Name: "Chris", Info: { Subject: "MongoDB", Marks: 67 } },
{ Name: "David", Info: { Subject: "MySQL", Marks: 78 } }
]
});
> db.demo465.insertOne({
id: 102,
details: [
{ Name: "Bob", Info: { Subject: "Java", Marks: 45 } },
{ Name: "Carol", Info: { Subject: "C", Marks: 67 } }
]
});
Query หาเอกสารที่มี details.Name = "Bob"
> db.demo465.find({ "details.Name": "Bob" });
ผลลัพธ์
{ "_id": ObjectId(...), "id": 102, "details": [{ "Name": "Bob", "Info": { "Subject": "Java", "Marks": 45 } }, { "Name": "Carol", "Info": { "Subject": "C", "Marks": 67 } }] }
คำอธิบาย
"details.Name"- MongoDB จะค้นหาในทุกอิลิเมนต์ของอาร์เรย์ details- ถ้าอิลิเมนต์ไหนมี Name = "Bob" เอกสารทั้งฉบับจะถูกคืน (รวมอิลิเมนต์อื่นในอาร์เรย์ด้วย)
- ใช้ index ได้หากสร้าง index บน
"details.Name"
เปรียบเทียบกับ $elemMatch
| Query | พฤติกรรม |
|---|---|
| { "details.Name": "Bob" } | คืนเอกสารทั้งฉบับ (รวมอิลิเมนต์อื่นใน details) |
| { details: { $elemMatch: { Name: "Bob" } } } | คืนเอกสารทั้งฉบับ (เหมือนกันสำหรับเงื่อนไขเดียว) |
| { details: { $elemMatch: { Name: "Bob", "Info.Marks": { $gt: 50 } } } } | คืนเฉพาะเอกสารที่มีอิลิเมนต์ เดียวกัน ตรงทั้ง 2 เงื่อนไข |
หากต้องการคืนเฉพาะอิลิเมนต์ที่ match
// ใช้ aggregation $filter
db.demo465.aggregate([
{ $match: { "details.Name": "Bob" } },
{ $project: { details: { $filter: { input: "$details", as: "d", cond: { $eq: ["$$d.Name", "Bob"] } } } } }
]);