เมื่อต้องการค้นหาเอกสารที่ array field (subcollection) มี element ตรงกับเงื่อนไขหลายอย่าง ให้ใช้ $elemMatch ร่วมกับ $in แทนการใช้ $and เพื่อประสิทธิภาพและความถูกต้องที่ดีกว่า
สร้างคอลเลกชันและข้อมูลตัวอย่าง
> db.demo83.insertOne({
... "Details":[
... {
... "Name":"Chris",
... "Subject":["MySQL", "MongoDB"]
... },
... {
... "Name":"David",
... "Subject":["Java", "C"]
... }
... ]
... });
{ "acknowledged" : true, "insertedId" : ObjectId("5e2bfd2271bf0181ecc422a3") }
> db.demo83.insertOne({
... "Details":[
... {
... "Name":"Bob",
... "Subject":["C++", "Python"]
... },
... {
... "Name":"John",
... "Subject":["Spring", "Hibernate"]
... }
... ]
... });
{ "acknowledged" : true, "insertedId" : ObjectId("5e2bfd4571bf0181ecc422a4") }
แสดงข้อมูลทั้งหมด
> db.demo83.find();
ผลลัพธ์:
{ "_id" : ObjectId("5e2bfd2271bf0181ecc422a3"), "Details" : [
{ "Name" : "Chris", "Subject" : [ "MySQL", "MongoDB" ] },
{ "Name" : "David", "Subject" : [ "Java", "C" ] }
]}
{ "_id" : ObjectId("5e2bfd4571bf0181ecc422a4"), "Details" : [
{ "Name" : "Bob", "Subject" : [ "C++", "Python" ] },
{ "Name" : "John", "Subject" : [ "Spring", "Hibernate" ] }
]}
Query ค้นหาด้วย $elemMatch และ $in
> db.demo83.find({
"Details" : {
"$elemMatch" : {
"Name" : "Chris",
"Subject": {"$in": ["MongoDB"]}
}
}
});
คำอธิบาย:
$elemMatch: ระบุเงื่อนไขสำหรับ element เดียวใน array Details$in: ["MongoDB"]: ตรวจสอบว่า array Subject มีค่า "MongoDB" อยู่หรือไม่- วิธีนี้มีประสิทธิภาพดีกว่า $and และให้ผลลัพธ์ถูกต้องมากกว่า
ผลลัพธ์
{ "_id" : ObjectId("5e2bfd2271bf0181ecc422a3"), "Details" : [
{ "Name" : "Chris", "Subject" : [ "MySQL", "MongoDB" ] },
{ "Name" : "David", "Subject" : [ "Java", "C" ] }
]}
คืนค่าเอกสารทั้งหมดที่มี element ใน Details ตรงกับเงื่อนไข (Name=Chris และ Subject มี MongoDB)
สรุป: ใช้ $elemMatch + $in สำหรับ query subcollection หลายเงื่อนไข แทน $and จะได้ผลถูกต้องและเร็วกว่า