ใช้ $match ใน Aggregation Pipeline เพื่อกรองเอกสารตามสตริงในอาร์เรย์
Stage $match ใน Aggregation Pipeline ทำงานคล้าย find() แต่ใช้ได้ภายใน Pipeline เพื่อกรองเอกสารก่อนส่งต่อ stage ถัดไป
ตัวอย่างข้อมูลทดสอบ
> db.demo424.insert({ "Information": [{ id: 10, Name: "Chris" }, { id: 11, Name: "David" }] });
> db.demo424.insert({ "Information": [{ id: 101, Name: "Mike" }, { id: 102, Name: "John" }] });
แสดงข้อมูลทั้งหมด
> db.demo424.find();
ผลลัพธ์:
{ "_id": ObjectId("..."), "Information": [{ "id": 10, "Name": "Chris" }, { "id": 11, "Name": "David" }] }
{ "_id": ObjectId("..."), "Information": [{ "id": 101, "Name": "Mike" }, { "id": 102, "Name": "John" }] }
คำสั่ง Aggregation ค้นหาเอกสารที่มี Information.Name = "Chris"
> db.demo424.aggregate([
{ $match: { "Information.Name": "Chris" } }
]);
ผลลัพธ์ที่ได้
{ "_id": ObjectId("..."), "Information": [{ "id": 10, "Name": "Chris" }, { "id": 11, "Name": "David" }] }
คำอธิบาย
- $match: { "Information.Name": "Chris" }: กรองเอกสารที่อาร์เรย์ Information มีออบเจกต์อย่างน้อย 1 ตัวที่ Name = "Chris"
- คืนเอกสารทั้งชิ้น (รวม Information อื่นๆ ที่ไม่ใช่ Chris ด้วย)
ความแตกต่างระหว่าง find() และ $match
| find() | $match ใน Aggregation |
|---|---|
| คำสั่งระดับบนสุด (Top-level) | Stage ใน Pipeline |
| คืน Cursor | ส่งต่อไปยัง Stage ถัดไป | ใช้ได้เลย | ต้องอยู่ใน aggregate([...]) |
| ไม่สามารถใช้ฟิลด์ที่คำนวณได้ | ใช้ฟิลด์ที่สร้างจาก $addFields, $project ได้ |
กรณีต้องการเฉพาะออบเจกต์ที่ Match (ใช้ $filter)
> db.demo424.aggregate([
{ $match: { "Information.Name": "Chris" } },
{ $project: { Information: { $filter: { input: "$Information", as: "i", cond: { $eq: ["$$i.Name", "Chris"] } } } } }
]);
จะได้เฉพาะ { "id": 10, "Name": "Chris" } ในอาร์เรย์ Information