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

MongoDB: ดึง Embedded Documents ที่มีสถานะ isMarried ทั้งหมด

การดึงเฉพาะ 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

กรณี Embedded Document ใน Array

หาก details เป็น array ใช้ $unwind ก่อน:

db.collection.aggregate([
  { $unwind: "$details" },
  { $project: { isMarried: "$details.isMarried", detailsId: "$details._id" }}
])

สรุป: $project ใน aggregate = เปลี่ยนโครงสร้าง document ได้อย่างยืดหยุ่น (rename, flatten, compute) | find projection = เร็วกว่า สำหรับดึง field แบบง่าย

FeatureAggregate $projectFind Projection
Rename field✓ (newName: "$old.path")✗ (keep original structure)
Compute new field✓ (expression)✗
Flatten nested✓✗
PerformanceSlower (pipeline)Faster (direct)