การ Query ค่า Nested (Nested Field) ใน MongoDB
ใช้ Dot Notation (เครื่องหมายจุด) เพื่อเข้าถึงฟิลด์ภายใน Object/Document ที่ซ้อนกัน (Nested Document)
ตัวอย่างการสร้างคอลเลกชันและเพิ่มข้อมูล Nested
> db.nestedQueryDemo.insertOne({
"EmployeeName": "John",
"EmployeeDetails": {
"_id": "EMP-101",
"EmployeeAge": 23,
"EmployeeCompanyName": "IBM"
}
});
{ "acknowledged" : true, "insertedId" : ObjectId("5c9ea31dd628fa4220163b69") }
> db.nestedQueryDemo.insertOne({
"EmployeeName": "Carol",
"EmployeeDetails": {
"_id": "EMP-110",
"EmployeeAge": 29,
"EmployeeCompanyName": "Amazon"
}
});
{ "acknowledged" : true, "insertedId" : ObjectId("5c9ea36bd628fa4220163b6a") }
แสดงข้อมูลทั้งหมด
> db.nestedQueryDemo.find().pretty();
ผลลัพธ์:
{
"_id" : ObjectId("5c9ea31dd628fa4220163b69"),
"EmployeeName" : "John",
"EmployeeDetails" : {
"_id" : "EMP-101",
"EmployeeAge" : 23,
"EmployeeCompanyName" : "IBM"
}
}
{
"_id" : ObjectId("5c9ea36bd628fa4220163b6a"),
"EmployeeName" : "Carol",
"EmployeeDetails" : {
"_id" : "EMP-110",
"EmployeeAge" : 29,
"EmployeeCompanyName" : "Amazon"
}
}
Query Nested Field ด้วย Dot Notation
> db.nestedQueryDemo.find({"EmployeeDetails._id": "EMP-110"}).pretty();
ผลลัพธ์ (พบ Carol):
{
"_id" : ObjectId("5c9ea36bd628fa4220163b6a"),
"EmployeeName" : "Carol",
"EmployeeDetails" : {
"_id" : "EMP-110",
"EmployeeAge" : 29,
"EmployeeCompanyName" : "Amazon"
}
}
คำอธิบาย Dot Notation
- "parent.child" : เข้าถึงฟิลด์ child ภายใน object parent
- "parent.child.grandchild" : เข้าถึงได้หลายระดับ
- ต้องใส่ใน Quotes : ใช้ " " ครอบทั้ง path
ตัวอย่าง Query Nested เพิ่มเติม
// ค้นหาตาม Company Name
db.nestedQueryDemo.find({ "EmployeeDetails.EmployeeCompanyName": "IBM" });
// ค้นหาตาม Age ใน Nested
db.nestedQueryDemo.find({ "EmployeeDetails.EmployeeAge": { $gt: 25 } });
// ค้นหาหลายเงื่อนไขใน Nested Object เดียวกัน
db.nestedQueryDemo.find({
"EmployeeDetails.EmployeeCompanyName": "Amazon",
"EmployeeDetails.EmployeeAge": { $gte: 25 }
});
// ใช้ $elemMatch สำหรับ Array of Objects
db.collection.find({
"employees": {
$elemMatch: {
"name": "John",
"age": { $gt: 25 }
}
}
});
Projection (เลือกฟิลด์) กับ Nested Field
// ดึงเฉพาะ Nested Field
db.nestedQueryDemo.find({}, { "EmployeeDetails.EmployeeCompanyName": 1, _id: 0 });
// ดึง Nested Object ทั้งหมด
db.nestedQueryDemo.find({}, { "EmployeeDetails": 1, _id: 0 });
// Exclude Nested Field
db.nestedQueryDemo.find({}, { "EmployeeDetails.EmployeeAge": 0 });
Index บน Nested Field
// สร้าง Index บน Nested Field
db.nestedQueryDemo.createIndex({ "EmployeeDetails.EmployeeCompanyName": 1 });
// Compound Index
db.nestedQueryDemo.createIndex({
"EmployeeDetails.EmployeeCompanyName": 1,
"EmployeeDetails.EmployeeAge": -1
});
ข้อควรระวัง
- Dot Notation ใน Query : ต้องใส่ใน Quotes "parent.child"
- Dot Notation ใน Update : ใช้ได้เหมือนกัน { $set: { "parent.child": value } }
- Array Index : เข้าถึง Array element ได้ด้วย "array.0.field" (Index เริ่มจาก 0)
- ประสิทธิภาพ : สร้าง Index บน Nested Field ที่ Query บ่อย
ตัวอย่าง Array Index
{ "tags": [ { "name": "mongodb", "type": "db" }, { "name": "javascript", "type": "lang" } ] }
// เข้าถึง element แรก
db.collection.find({ "tags.0.name": "mongodb" });
// เข้าถึง element ที่ 2
db.collection.find({ "tags.1.type": "lang" });