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

วิธีอัปเดตค่า Key ใน Array ของ JSON Document ใน MongoDB

MongoDB ไม่มี operator ตรงๆ สำหรับ update ทุก element ใน Array of Objects ต้องดึงเอกสารมา แก้ไขใน JavaScript แล้ว $set ทับกลับไป

แนวคิด

  1. findOne() ดึงเอกสารมา
  2. วนลูป forEach() แก้ค่าใน Array
  3. update() + $set เขียนทับ Array ทั้งชุด

ตัวอย่างเต็มรูปแบบ

1. สร้างข้อมูล: Document มี Array of Objects

> db.updateListOfKeyValuesDemo.insertOne({
    "StudentDetails": [
        { "StudentName": "John", "StudentAge": 23, "StudentCountryName": "US" },
        { "StudentName": "Carol", "StudentAge": 24, "StudentCountryName": "UK" },
        { "StudentName": "Bob", "StudentAge": 22, "StudentCountryName": "AUS" }
    ]
});

2. แสดงข้อมูลก่อน

> db.updateListOfKeyValuesDemo.find().pretty();
{ 
    "_id" : ObjectId("..."), 
    "StudentDetails" : [ 
        { "StudentName" : "John", "StudentAge" : 23, "StudentCountryName" : "US" },
        { "StudentName" : "Carol", "StudentAge" : 24, "StudentCountryName" : "UK" },
        { "StudentName" : "Bob", "StudentAge" : 22, "StudentCountryName" : "AUS" }
    ]
}

3. อัปเดต StudentName ทุกตัวเป็น "Ramit"

> var documentFromCollection = db.updateListOfKeyValuesDemo.findOne({ 
    "_id": ObjectId("5c9b5b759882024390176545") 
});

> documentFromCollection.StudentDetails.forEach(function(updateStudent) {
    updateStudent.StudentName = "Ramit";
});

> db.updateListOfKeyValuesDemo.update(
    { "_id": documentFromCollection._id },
    { $set: { "StudentDetails": documentFromCollection.StudentDetails } }
);
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

4. ผลลัพธ์: ทุก StudentName กลายเป็น Ramit

> db.updateListOfKeyValuesDemo.find().pretty();
{ 
    "_id" : ObjectId("..."), 
    "StudentDetails" : [ 
        { "StudentName" : "Ramit", "StudentAge" : 23, "StudentCountryName" : "US" },
        { "StudentName" : "Ramit", "StudentAge" : 24, "StudentCountryName" : "UK" },
        { "StudentName" : "Ramit", "StudentAge" : 22, "StudentCountryName" : "AUS" }
    ]
}

วิธีสมัยใหม่: ใช้ $[] + arrayFilters (MongoDB 3.6+)

db.collection.updateMany(
    {},
    { $set: { "StudentDetails.$[elem].StudentName": "Ramit" } },
    { arrayFilters: [ { "elem.StudentName": { $exists: true } } ] }
);

วิธีนี้ทำได้ใน Server-side ไม่ต้องดึงมาประมวลผลฝั่ง Client

สรุป

  • Legacy: ดึงมา → Loop แก้ → $set ทับ Array ทั้งชุด
  • Modern (3.6+): ใช้ arrayFilters + $[identifier] อัปเดตใน Server
  • ต้องระวัง Race Condition (ใช้ findAndModify หรือ Transaction)
  • เหมาะกับ Array ขนาดเล็ก สำหรับ Array ใหญ่ควรแยก Collection