การ query เข้าถึง nested array string (array ใน object ใน array) ใน MongoDB ทำได้ง่ายด้วย Dot Notation ใน find() โดยไม่ต้องใช้ aggregate
สร้างคอลเลกชันและข้อมูลตัวอย่าง
> db.demo89.insertOne({
id: 101, Details: [
{ Name: "Chris", Marks: 45 },
{ Name: "David", Marks: 55, Subjects : ["MySQL", "MongoDB", "Java", "C"] }
]
});
{ "acknowledged" : true, "insertedId" : ObjectId("5e2c163b79799acab037af51") }
> db.demo89.insertOne({
id: 102, Details: [
{ Name: "Mike", Marks: 48 },
{ Name: "Bob", Marks: 98, Subjects : ["C++", "MySQL"] }
]
});
{ "acknowledged" : true, "insertedId" : ObjectId("5e2c163c79799acab037af52") }
แสดงข้อมูลทั้งหมด
> db.demo89.find();
ผลลัพธ์: 2 เอกสาร แต่ละอันมี Details array 2 elements, element ที่ 2 มี Subjects array
Query ค้นหาเอกสารที่มี Subject "MongoDB" ใน Nested Array
> db.demo89.find({ "Details.Subjects": "MongoDB" });
ผลลัพธ์
{ "_id" : ObjectId("5e2c163b79799acab037af51"), "id" : 101, "Details" : [
{ "Name" : "Chris", "Marks" : 45 },
{ "Name" : "David", "Marks" : 55, "Subjects" : [ "MySQL", "MongoDB", "Java", "C" ] }
] }
คำอธิบาย:
Details.Subjects: MongoDB จะค้นหาใน ทุก element ของ array Details, และใน ทุก element ของ array Subjects ภายใน- ไม่ต้องระบุ index (Details.0.Subjects) - MongoDB จะตรวจสอบทุกระดับอัตโนมัติ
- คืนค่าเอกสารทั้งหมดที่มี element ใด element หนึ่ง match
การใช้ $elemMatch สำหรับเงื่อนไขซับซ้อน
หากต้องการจับคู่หลาย field ใน element เดียวของ Details:
db.demo89.find({
Details: {
$elemMatch: {
Name: "David",
Subjects: "MongoDB"
}
}
})
Projection: ดึงเฉพาะ Nested Array
ใช้ $elemMatch ใน projection เพื่อคืนค่าเฉพาะ element ที่ match:
db.demo89.find(
{ "Details.Subjects": "MongoDB" },
{ "Details": { $elemMatch: { "Subjects": "MongoDB" } } }
)
สรุป: Dot notation ทำให้ query nested array ง่ายมาก ไม่ต้อง unwind หรือ aggregate สำหรับการค้นหาแบบง่าย