Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MongoDB

MongoDB Query สำหรับฟิลด์ใน Embedded Document (Array of Objects)

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 ใน projection
    db.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 ใน Query
    db.embeddedDocumentDemo.find({
      CustomerDetails: {$elemMatch: {CustomerName: "Robert", CustomerPurchasePrice: 4500}}
    });