ค้นหาเอกสารที่ตรงตามเงื่อนไขหลายฟิลด์พร้อมกันด้วย $and และ $in
เมื่อต้องการ Exact Match หลายฟิลด์พร้อมกัน (AND logic ระหว่างฟิลด์) และแต่ละฟิลด์รับค่าได้หลายค่า (OR logic ภายในฟิลด์) ให้ใช้ $and ร่วมกับ $in
ตัวอย่างข้อมูลทดสอบ
> db.demo422.insertOne({ "Name": "Chris", "Marks": 34 });
> db.demo422.insertOne({ "Name": "Chris", "Marks": 56 });
> db.demo422.insertOne({ "Name": "David", "Marks": 78 });
> db.demo422.insertOne({ "Name": "Sam", "Marks": 45 });
> db.demo422.insertOne({ "Name": "David", "Marks": 89 });
แสดงข้อมูลทั้งหมด
> db.demo422.find();
ผลลัพธ์: 5 เอกสาร
คำสั่งค้นหา: Name เป็น Chris หรือ David และ Marks เป็น 34 หรือ 89
> db.demo422.find({
$and: [
{ Name: { $in: ["Chris", "David"] } },
{ Marks: { $in: [34, 89] } }
]
});
ผลลัพธ์ที่ได้ (Exact Match ทั้งคู่)
{ "_id": ObjectId("..."), "Name": "Chris", "Marks": 34 }
{ "_id": ObjectId("..."), "Name": "David", "Marks": 89 }
คำอธิบาย
- $and: ทุกเงื่อนไขในอาร์เรย์ต้องเป็นจริงพร้อมกัน (AND ระหว่างฟิลด์)
- Name: { $in: ["Chris", "David"] }: Name ต้องเป็น Chris หรือ David (OR ภายในฟิลด์)
- Marks: { $in: [34, 89] }: Marks ต้องเป็น 34 หรือ 89 (OR ภายในฟิลด์)
- รวมกัน: (Chris OR David) AND (34 OR 89) -> ได้ (Chris,34) และ (David,89) เท่านั้น
รูปแบบที่เทียบเท่า (Implicit AND)
> db.demo422.find({
Name: { $in: ["Chris", "David"] },
Marks: { $in: [34, 89] }
});
ใน find() เงื่อนไขระดับบนสุดเป็น Implicit $and แล้ว เขียน $and เฉพาะต้องการ OR ระหว่างเงื่อนไขระดับบนสุด
กรณีซับซ้อน: OR ระหว่างเงื่อนไขชุด (ต้องใช้ $or)
> db.demo422.find({
$or: [
{ Name: "Chris", Marks: 34 },
{ Name: "David", Marks: 89 }
]
});
หา (Chris AND 34) OR (David AND 89) - เหมือน $and + $in แต่ควบคุมคู่ได้ชัดเจนกว่า
ประสิทธิภาพ
- สร้าง Compound Index:
db.demo422.createIndex({ Name: 1, Marks: 1 }) - $in ใช้ดัชนีได้ (Multi-key bounds)
- หลีกเลี่ยง $or มากเกินไป (อาจไม่ใช้ดัชนีได้เต็มที่)