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

MongoDB Query: กรองข้อมูลด้วยหลาย Array Elements ($elemMatch)

เมื่อต้องการค้นหาเอกสารที่ array field มี element ตรงกับหลายเงื่อนไขพร้อมกัน ให้ใช้ $elemMatch ซึ่งจะจับคู่ element เดียวที่ตรงทุกเงื่อนไข

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

> db.demo87.insertOne({
  id:101,
  "Details": [
    { "EmployeeName": "Chris", "Salary": 45000 },
    { "EmployeeName": "David", "Salary": 50000 }
  ]
});
{ "acknowledged" : true, "insertedId" : ObjectId("5e2c113871bf0181ecc422ab") }
> db.demo87.insertOne({
  id:102,
  "Details": [
    { "EmployeeName": "Chris", "Salary": 65000 },
    { "EmployeeName": "Mike", "Salary": 100000 }
  ]
});
{ "acknowledged" : true, "insertedId" : ObjectId("5e2c114371bf0181ecc422ac") }

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

> db.demo87.find();

ผลลัพธ์: 2 เอกสาร ทั้งคู่มี Chris ใน Details แต่ Salary ต่างกัน

Query กรองด้วย $elemMatch หลายเงื่อนไข

> db.demo87.find({ Details: { $elemMatch: { "EmployeeName": 'Chris', "Salary": 65000 }}});

ผลลัพธ์

{ "_id" : ObjectId("5e2c114371bf0181ecc422ac"), "id" : 102, "Details" : [
  { "EmployeeName" : "Chris", "Salary" : 65000 },
  { "EmployeeName" : "Mike", "Salary" : 100000 }
] }

คำอธิบาย:

  • เอกสาร id=101: มี Chris แต่ Salary=45000 → ไม่ตรง
  • เอกสาร id=102: มี Chris และ Salary=65000 ใน element เดียวกัน → ตรง

ความแตกต่าง: $elemMatch vs Query ธรรมดา

Query ธรรมดา (ผิดสำหรับกรณีนี้):

db.demo87.find({ "Details.EmployeeName": "Chris", "Details.Salary": 65000 })

จะคืนค่า ทั้งสองเอกสาร เพราะ MongoDB match EmployeeName จาก element ตัวแรก และ Salary จาก element ตัวที่สอง (cross-match)

$elemMatch (ถูกต้อง): ต้องเป็น element เดียวกันที่ตรงทั้งสอง field

ใช้ $elemMatch ใน Projection

คืนค่าเฉพาะ element ที่ match:

db.demo87.find(
  { Details: { $elemMatch: { "EmployeeName": 'Chris', "Salary": 65000 }}},
  { Details: { $elemMatch: { "EmployeeName": 'Chris', "Salary": 65000 }} }
)

กรณีเงื่อนไขซับซ้อนมากขึ้น

db.demo87.find({
  Details: {
    $elemMatch: {
      EmployeeName: "Chris",
      Salary: { $gte: 60000, $lte: 70000 }
    }
  }
})

สรุป: ใช้ $elmMatch เสมอเมื่อ query array of objects หลาย field พร้อมกัน เพื่อความถูกต้อง