MongoDB ไม่มี operator ตรงๆ สำหรับ update ทุก element ใน Array of Objects ต้องดึงเอกสารมา แก้ไขใน JavaScript แล้ว $set ทับกลับไป
แนวคิด
findOne()ดึงเอกสารมา- วนลูป
forEach()แก้ค่าใน Array 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