การดึงเฉพาะ field จาก embedded document (nested object) ใน MongoDB ใช้ $project ใน aggregate pipeline เพื่อ reshape document structure
สร้างคอลเลกชันและข้อมูลตัวอย่าง
> db.demo220.insertOne({
"id": 101,
"FullName" : "John Doe",
"EmailId" : "john12@gmail.com",
"ShippingDate" : new ISODate(),
"details" : { "_id" : 1001, "isMarried" : true }
});
{ "acknowledged" : true, "insertedId" : ObjectId("5e3eaf5b03d395bdc213471d") }
> db.demo220.insertOne({
"id": 102,
"FullName" : "John Smith",
"EmailId" : "johnsmith@gmail.com",
"ShippingDate" : new ISODate(),
"details" : { "_id" : 1002, "isMarried" : false }
});
{ "acknowledged" : true, "insertedId" : ObjectId("5e3eaf5c03d395bdc213471e") }
แสดงข้อมูลทั้งหมด
> db.demo220.find();
ผลลัพธ์: 2 เอกสาร แต่ละอันมี embedded object details (มี _id, isMarried)
Query ดึงเฉพาะ isMarried และ details._id ด้วย $project
> db.demo220.aggregate([
{ $project: {
"isMarried": "$details.isMarried",
"detailsId": "$details._id"
}}
]);
คำอธิบาย:
$project: กำหนด field ที่จะรวมใน output (1 = include, 0 = exclude)"isMarried": "$details.isMarried": สร้าง field ใหม่ isMarried จาก nested path"detailsId": "$details._id": สร้าง field ใหม่ detailsId จาก nested _id- _id จะถูกรวมอัตโนมัติ (ต้องระบุ
_id: 0ถ้าไม่ต้องการ)
ผลลัพธ์
{ "_id" : ObjectId("5e3eaf5b03d395bdc213471d"), "isMarried" : true }
{ "_id" : ObjectId("5e3eaf5c03d395bdc213471e"), "isMarried" : false }
ได้เฉพาะ isMarried (และ _id) ไม่มี detailsId เพราะ typo ใน query ต้นฉบับ ($details_id แทน $details._id) - ตัวอย่างนี้แก้ไขแล้ว
Projection ใน find() (Alternative)
สำหรับการดึง field nested แบบง่าย ใช้ find() projection:
db.demo220.find({}, {"details.isMarried": 1, "details._id": 1, _id: 0})
// { "details" : { "_id" : 1001, "isMarried" : true } }
// { "details" : { "_id" : 1002, "isMarried" : false } }
Aggregate $project vs Find Projection
| Feature | Aggregate $project | Find Projection |
|---|---|---|
| Rename field | ✓ (newName: "$old.path") | ✗ (keep original structure) |
| Compute new field | ✓ (expression) | ✗ |
| Flatten nested | ✓ | ✗ |
| Performance | Slower (pipeline) | Faster (direct) |