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

MongoDB Query: อัปเดตออบเจ็กต์ในอาร์เรย์ที่ Index N


ใช้ Positional $ Operator กับ Dot Notation

เมื่อต้องการอัปเดตอิลิเมนต์เฉพาะในอาร์เรย์ของออบเจ็กต์ ใช้ query match ฟิลด์ในอิลิเมนต์ แล้วอัปเดตด้วย $ (positional operator)

ตัวอย่างข้อมูล

> db.demo489.insertOne({
  details: [
    { id: 101, Info1: { StudentName: "Chris" }, Info2: { TeacherName: "David" } },
    { id: 102, Info1: { StudentName: "Carol" }, Info2: { TeacherName: "Mike" } }
  ]
});

Query อัปเดตอิลิเมนต์ id=102

> db.demo489.update(
  { "details.id": 102 },
  { $set: {
      "details.$.Info1.StudentName": "Robert",
      "details.$.Info2.TeacherName": "John",
      "details.$.CountryName": "US"
  }}
);
WriteResult({ "nMatched": 1, "nUpserted": 0, "nModified": 1 })

ผลลัพธ์

{ "_id": ObjectId(...), "details": [
  { "id": 101, "Info1": { "StudentName": "Chris" }, "Info2": { "TeacherName": "David" } },
  { "id": 102, "Info1": { "StudentName": "Robert" }, "Info2": { "TeacherName": "John" }, "CountryName": "US" }
] }

คำอธิบาย

  • { "details.id": 102 } - หาเอกสารที่มีอิลิเมนต์ใน details.id = 102
  • details.$ - อ้างอิง **อิลิเมนต์แรกที่ match** ในอาร์เรย์ details
  • อัปเดตฟิลด์ซ้อน: Info1.StudentName, Info2.TeacherName
  • เพิ่มฟิลด์ใหม่: CountryName ในอิลิเมนต์เดียวกัน

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

  • อัปเดตได้ **อิลิเมนต์แรกที่ match** เท่านั้น
  • ไม่รองรับ nested array (อาร์เรย์ในอาร์เรย์)
  • query ต้อง match ฟิลด์ในอิลิเมนต์เดียวกับที่จะอัปเดต

ทางเลือก: ArrayFilters (MongoDB 3.6+)

db.demo489.updateOne(
  { "details.id": 102 },
  { $set: { "details.$[elem].Info1.StudentName": "Robert" } },
  { arrayFilters: [{ "elem.id": 102 }] }
);

// อัปเดตทุกอิลิเมนต์ที่ match
db.demo489.updateMany(
  {},
  { $set: { "details.$[elem].Status": "Active" } },
  { arrayFilters: [{ "elem.id": { $gte: 100 } }] }
);

รูปแบบใหม่แนะนำ

// ใช้ updateOne/updateMany แทน update()
db.demo489.updateOne(
  { "details.id": 102 },
  { $set: { "details.$.Info1.StudentName": "Robert" } }
);