MongoDB สามารถ Query ฟิลด์ภายใน Object ที่อยู่ใน Array (Embedded Document) ได้โดยตรงด้วย Dot Notation โดยไม่ต้อง Unwind ก่อน
สร้างคอลเลกชันและข้อมูลตัวอย่าง
> db.embeddedDocumentDemo.insertOne({
"CustomerDetails": [
{"CustomerName": "Chris", "CustomerPurchasePrice": 3000},
{"CustomerName": "Robert", "CustomerPurchasePrice": 4500},
{"CustomerName": "David", "CustomerPurchasePrice": 1000}
]
});
{ "acknowledged": true, "insertedId": ObjectId("5cd32347edc6604c74817ccd") }
แสดงข้อมูล
> db.embeddedDocumentDemo.find().pretty();
ผลลัพธ์: 1 เอกสาร มี Array CustomerDetails 3 Elements
{
"_id": ObjectId("5cd32347edc6604c74817ccd"),
"CustomerDetails": [
{"CustomerName": "Chris", "CustomerPurchasePrice": 3000},
{"CustomerName": "Robert", "CustomerPurchasePrice": 4500},
{"CustomerName": "David", "CustomerPurchasePrice": 1000}
]
}
ค้นหาเอกสารที่มี CustomerPurchasePrice = 4500 ใน Array
> db.embeddedDocumentDemo.find({"CustomerDetails.CustomerPurchasePrice": 4500});
ผลลัพธ์: คืนเอกสารทั้งอัน (เพราะมี Element หนึ่งใน Array ตรงเงื่อนไข)
{
"_id": ObjectId("5cd32347edc6604c74817ccd"),
"CustomerDetails": [
{"CustomerName": "Chris", "CustomerPurchasePrice": 3000},
{"CustomerName": "Robert", "CustomerPurchasePrice": 4500},
{"CustomerName": "David", "CustomerPurchasePrice": 1000}
]
}
การทำงาน
- MongoDB สแกนทุก Element ใน Array
CustomerDetails - หาก Element ใดมี
CustomerPurchasePrice = 4500→ คืนเอกสารทั้งอัน - ไม่คืนแค่ Element ที่ตรง (ต้องใช้ Aggregation $filter หรือ $elemMatch ใน Projection)
เทคนิคเพิ่มเติม
- Projection เฉพาะ Element ที่ตรง: ใช้
$elemMatchใน projectiondb.embeddedDocumentDemo.find( {"CustomerDetails.CustomerPurchasePrice": 4500}, {"CustomerDetails": {$elemMatch: {"CustomerPurchasePrice": 4500}}} ); - Aggregation $filter เพื่อคืน Sub-array ที่กรองแล้ว:
db.embeddedDocumentDemo.aggregate([ {$project: { CustomerDetails: { $filter: { input: "$CustomerDetails", cond: {$eq: ["$$this.CustomerPurchasePrice", 4500]} } } }} ]); - Query หลายเงื่อนไขใน Object เดียวกัน: ใช้
$elemMatchใน Querydb.embeddedDocumentDemo.find({ CustomerDetails: {$elemMatch: {CustomerName: "Robert", CustomerPurchasePrice: 4500}} });