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

การค้นหาในอาร์เรย์ออบเจกต์ตาม _id ด้วย Aggregation ใน MongoDB

ใช้ $unwind และ $match เพื่อค้นหาในอาร์เรย์ออบเจกต์

เมื่อต้องการค้นหาเอกสารที่มีอาร์เรย์ของออบเจกต์ และต้องการคืนค่าเฉพาะออบเจกต์ที่ match (ไม่ใช่เอกสารทั้งชิ้น) ให้ใช้ Aggregation Pipeline พร้อม $unwind และ $match

ตัวอย่างข้อมูลทดสอบ

> db.demo414.insertOne({
  "_id": "110",
  "details": [
    { "StudentName": "John", "StudentMarks": 56 },
    { "StudentName": "Robert", "StudentMarks": 98 }
  ]
});

แสดงข้อมูล

> db.demo414.find();

ผลลัพธ์:

{ "_id": "110", "details": [{ "StudentName": "John", "StudentMarks": 56 }, { "StudentName": "Robert", "StudentMarks": 98 }] }

คำสั่ง Aggregation หา details ที่ StudentMarks = 56

> db.demo414.aggregate([
  { $unwind: "$details" },
  { $match: { "details.StudentMarks": 56 } }
]);

ผลลัพธ์ที่ได้

{ "_id": "110", "details": { "StudentName": "John", "StudentMarks": 56 } }

คำอธิบาย

  • $unwind: "$details": แยกอาร์เรย์ details ให้แต่ละออบเจกต์กลายเป็นเอกสารแยกกัน (duplicate _id)
  • $match: { "details.StudentMarks": 56 }: กรองเฉพาะเอกสารที่ StudentMarks = 56
  • ผลลัพธ์คือเอกสารที่มี details เป็นออบเจกต์เดียว (ไม่ใช่อาร์เรย์)

กรณีต้องการคืนค่าเป็นอาร์เรย์กลับไป (MongoDB 3.6+)

> db.demo414.aggregate([
  { $match: { "details.StudentMarks": 56 } },
  { $project: { details: { $filter: { input: "$details", as: "d", cond: { $eq: ["$$d.StudentMarks", 56] } } } } }
]);

ใช้ $filter เพื่อกรองภายในอาร์เรย์โดยไม่ต้อง $unwind คืนค่าเป็นอาร์เรย์เหมือนเดิม

เปรียบเทียบ find() vs Aggregation

find()Aggregation ($unwind + $match)
คืนเอกสารทั้งชิ้นคืนเฉพาะออบเจกต์ที่ match
ไม่สามารถกรองภายในอาร์เรย์ได้กรองภายในอาร์เรย์ได้
เร็วกว่าสำหรับคิวรีง่ายยืดหยุ่นกว่า สร้างฟิลด์ใหม่ได้