ใช้ Aggregation Pipeline: $unwind แยก Array → $match กรอง → $group รวมกลับ → $project จัดรูปแบบ เพื่อดึงหลายรายการที่ตรงเงื่อนไขจาก Array of Objects
สร้างคอลเลกชันและข้อมูลตัวอย่าง
> db.retrieveMultipleDemo.insertOne({
"UserDetails": [
{"_id": "101", "UserName": "John", "UserAge": 23},
{"_id": "102", "UserName": "Carol", "UserAge": 21},
{"_id": "103", "UserName": "David", "UserAge": 23},
{"_id": "104", "UserName": "Sam", "UserAge": 25}
]
});
{ "acknowledged": true, "insertedId": ObjectId("5cd40c85edc6604c74817cf0") }
แสดงข้อมูล
> db.retrieveMultipleDemo.find().pretty();
ผลลัพธ์: 1 เอกสาร มี Array UserDetails 4 Elements
Aggregation: ดึง User ที่ Age = 23 และ _id ใน [101, 103]
> db.retrieveMultipleDemo.aggregate([
{$unwind: "$UserDetails"},
{$match: {"UserDetails._id": {$in: ["101", "103"]}, "UserDetails.UserAge": 23}},
{$group: {"_id": "$_id", "UserDetails": {$push: "$UserDetails"}}},
{$project: {"_id": 0, "UserDetails": 1}}
]);
ผลลัพธ์: ได้ John และ David (Age 23, ID ในรายการ)
{
"UserDetails": [
{"_id": "101", "UserName": "John", "UserAge": 23},
{"_id": "103", "UserName": "David", "UserAge": 23}
]
}
ขั้นตอน Pipeline
- $unwind: แยก Array UserDetails → 4 Documents (แต่ละ Document มี 1 UserDetail)
- $match: กรองเฉพาะที่ _id ใน ["101","103"] และ UserAge = 23
- $group: รวมกลับตาม _id ของ Document ต้นทาง ($push สร้าง Array ใหม่)
- $project: จัดรูปแบบ Output (ซ่อน _id, แสดง UserDetails)
ตัวแปร myIds ในตัวอย่างต้นฉบับ
โค้ดต้นฉบับใช้ myIds ซึ่งควรเป็น Array Variable ใน Shell:
var myIds = ["101", "103"];
db.retrieveMultipleDemo.aggregate([
{$unwind: "$UserDetails"},
{$match: {"UserDetails._id": {$in: myIds}, "UserDetails.UserAge": 23}},
{$group: {"_id": "$_id", "UserDetails": {$push: "$UserDetails"}}},
{$project: {"_id": 0, "UserDetails": 1}}
]);
เทคนิคเพิ่มเติม
- $replaceRoot แทน $group + $project (MongoDB 3.6+):
{$replaceRoot: {newRoot: "$UserDetails"}} - $elemMatch ใน find() สำหรับกรณีง่าย (คืน Element เดียว):
db.coll.find({}, {"UserDetails": {$elemMatch: {UserAge: 23}}}) - Performance: $unwind เพิ่ม Document Count → ใช้ $match ก่อน $unwind ถ้าเป็นไปได้ (แต่ Match ต้องอยู่ใน Array จึงต้อง Unwind ก่อน)