การเพิ่ม field ใหม่เข้าไปใน object ที่อยู่ใน array (nested field) ใช้ $set ร่วมกับ positional operator $ ใน update operation
สร้างคอลเลกชันและข้อมูลตัวอย่าง
> db.demo222.insertOne({
"details": [
{"StudentName":"Chris","StudentMarks":78},
{"StudentName":"David","StudentMarks":89}
]
});
{ "acknowledged" : true, "insertedId" : ObjectId("5e3ee31703d395bdc213472f") }
แสดงข้อมูลก่อนเพิ่ม Field
> db.demo222.find().pretty();
ผลลัพธ์: details array 2 elements (Chris, David) แต่ละอันมี StudentName, StudentMarks
Query เพิ่ม SubjectName ให้ Chris
> db.demo222.update(
{"details.StudentName" : "Chris"},
{"$set" : {"details.$.SubjectName":"MongoDB"}}
);
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
คำอธิบาย:
{"details.StudentName": "Chris"}: หาเอกสารที่ array details มี element ที่ StudentName="Chris"details.$.SubjectName:$= positional operator อ้างอิง element ที่ match filter (Chris)$set: เพิ่ม field ใหม่ SubjectName (หากมีอยู่จะ overwrite)
ผลลัพธ์หลังเพิ่ม Field
> db.demo222.find().pretty();
ผลลัพธ์:
{ "_id" : ObjectId("5e3ee31703d395bdc213472f"), "details" : [
{ "StudentName" : "Chris", "StudentMarks" : 78, "SubjectName" : "MongoDB" },
{ "StudentName" : "David", "StudentMarks" : 89 }
] }
Chris ได้ SubjectName เพิ่ม David ไม่ได้รับผลกระทบ
กรณีเพิ่ม Element ใหม่เข้า Array (ไม่ใช่ field ใน object)
ใช้ $push แทน:
db.demo222.update(
{_id: ObjectId("...")},
{$push: {details: {StudentName: "Bob", StudentMarks: 95}}}
)
เพิ่มหลาย Fields พร้อมกัน
db.demo222.update(
{"details.StudentName": "Chris"},
{$set: {
"details.$.SubjectName": "MongoDB",
"details.$.Grade": "A",
"details.$.UpdatedAt": new Date()
}}
)
ใช้ arrayFilters สำหรับ Multiple Matches (MongoDB 3.6+)
หากมี Chris หลายคนใน array เดียว และต้องการอัปเดตทุกคน:
db.demo222.updateMany(
{},
{$set: {"details.$[elem].SubjectName": "MongoDB"}},
{arrayFilters: [{"elem.StudentName": "Chris"}]}
)
ข้อจำกัดของ Positional $
- อัปเดตได้แค่ element แรก ที่ match filter
- ไม่ทำงานกับ nested arrays (array ใน array) ต้องใช้ arrayFilters
- Filter ต้อง match array field โดยตรง (ไม่ใช่ nested field)
สรุป: $set + positional $ = เพิ่ม/แก้ไข field ใน array element เป้าหมาย | $push = เพิ่ม element ใหม่เข้า array