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

ดึง Object เฉพาะจาก Array of Objects ใน MongoDB ด้วย Positional Operator ($)

ใช้ Positional Operator $ ใน Projection เพื่อคืนค่าเฉพาะ Element แรกใน Array ที่ตรงกับ Query Condition (Array of Objects)

สร้างคอลเลกชันและข้อมูลตัวอย่าง

> db.getASpecificObjectDemo.insertOne({
    _id: 1,
    "CustomerName": "Larry",
    "CustomerDetails": {
      "CustomerPurchaseDescription": [
        {"id": 100, "ProductName": "Product-1", "Amount": 10000},
        {"id": 101, "ProductName": "Product-2", "Amount": 10500},
        {"id": 102, "ProductName": "Product-3", "Amount": 10200}
      ]
    }
  });
{ "acknowledged": true, "insertedId": 1 }

แสดงข้อมูลทั้งหมด

> db.getASpecificObjectDemo.find().pretty();

ผลลัพธ์: Array มี 3 Products

Query: ดึงเฉพาะ Product ที่ id = 101

ใช้ Query Filter หา id ใน Array + Projection ด้วย $:

> db.getASpecificObjectDemo.find(
  {_id: 1, "CustomerDetails.CustomerPurchaseDescription.id": 101},
  {_id: 0, "CustomerDetails.CustomerPurchaseDescription.$": 1}
);

ผลลัพธ์: คืนเฉพาะ Element ที่ id=101

{
  "CustomerDetails": {
    "CustomerPurchaseDescription": [
      {"id": 101, "ProductName": "Product-2", "Amount": 10500}
    ]
  }
}

การทำงานของ Positional Operator $

  • คืนค่า Element แรก ใน Array ที่ Match Query Condition
  • ใช้ได้เฉพาะใน Projection (พารามิเตอร์ที่ 2 ของ find)
  • ต้องมี Query Condition บน Array Field เดียวกัน
  • หากมีหลาย Element Match → คืนแค่ตัวแรก

ข้อจำกัด

  • ใช้ได้ 1 ตำแหน่งต่อ Query (ไม่สามารถ $.field1, $.field2 แบบแยก Array ได้)
  • ไม่ทำงานกับ Nested Array หลายชั้น (ต้องใช้ Aggregation)
  • MongoDB 4.4+ ใช้ $ ใน Update ได้ (Filtered Positional Operator)

ทางเลือก: Aggregation $filter (ยืดหยุ่นกว่า)

db.getASpecificObjectDemo.aggregate([
  {$match: {_id: 1}},
  {$project: {
    CustomerDetails: {
      CustomerPurchaseDescription: {
        $filter: {
          input: "$CustomerDetails.CustomerPurchaseDescription",
          cond: {$eq: ["$$this.id", 101]}
        }
      }
    }
  }}
]);

ข้อดี: คืน Array ทั้งหมดที่ Match (ไม่ใช่แค่ตัวแรก), รองรับ Nested Array, ใช้ใน Pipeline ได้

สรุป: เลือกใช้ตัวไหน?

ความต้องการวิธีแนะนำ
Element เดียว แบบง่ายPositional $ ใน find()
หลาย Element / Complex FilterAggregation $filter
Nested Array (Array ใน Array)Aggregation $unwind + $filter
Update Element ใน ArrayFiltered Positional $[identifier] (MongoDB 4.4+)