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

ดึง Nested Object (ออบเจ็กต์ซ้อน) ใน MongoDB

ใช้ Positional Operator $ Project เฉพาะ Nested Object ที่ Match

เมื่อมี Array of Objects และต้องการ Return เฉพาะ Object ที่ Match เงื่อนไข ใช้ $ (Positional Projection) ใน Projection Document

ตัวอย่างข้อมูล: คะแนนวิชาต่างๆ ใน Array

> db.queryNestedObject.insertOne({
    "StudentName": "James",
    "StudentSubjectScore": [
        { "StudentMongoDBScore": 98 },
        { "StudentCScore": 92 },
        { "StudentJavaScore": 91 }
    ]
});

คิวรี: หา StudentJavaScore = 91 และ Project เฉพาะ Object นั้น

> db.queryNestedObject.find(
    { 'StudentSubjectScore.StudentJavaScore': 91 },
    { 'StudentSubjectScore.$': 1, _id: 0 }
);

ผลลัพธ์

{ "StudentSubjectScore" : [ { "StudentJavaScore" : 91 } ] }

คำอธิบาย

  • Query: StudentSubjectScore.StudentJavaScore ใช้ Dot Notation เข้า Array of Objects
  • Projection: StudentSubjectScore.$ Return เฉพาะ Element แรกที่ Match
  • _id: 0 ซ่อน _id

ข้อจำกัดของ Positional $

  • Return Element แรก ที่ Match เท่านั้น
  • ใช้ได้ 1 ตัวต่อ Query (ไม่รองรับ Multiple Positional)
  • ต้องมี Field Path ใน Query Condition

ทางเลือก: ใช้ $elemMatch ใน Projection (MongoDB 3.2+)

Return ทุก Element ที่ Match (ไม่ใช่แค่ตัวแรก)

db.queryNestedObject.find(
    { "StudentSubjectScore.StudentJavaScore": 91 },
    { StudentSubjectScore: { $elemMatch: { StudentJavaScore: 91 } }, _id: 0 }
);

Aggregation Alternative (ยืดหยุ่นที่สุด)

db.queryNestedObject.aggregate([
    { $match: { "StudentSubjectScore.StudentJavaScore": 91 } },
    { $project: {
        StudentName: 1,
        StudentSubjectScore: {
            $filter: {
                input: "$StudentSubjectScore",
                cond: { $eq: ["$$this.StudentJavaScore", 91] }
            }
        }
    }}
]);

Use Cases

  • Embedded Documents: Orders → Items, Users → Addresses
  • Versioned Data: Document → Versions Array
  • Category/Tag Systems: Product → Variants Array