การเพิ่มค่า (increment) ของ field ภายใน object ที่อยู่ใน array สามารถทำได้ด้วย update() ร่วมกับ positional operator $ และ $inc
สร้างคอลเลกชันและข้อมูลตัวอย่าง
> db.demo97.insertOne({
... "Details": [
... { "Name": "Chris", "Marks": 45 },
... { "Name": "Bob", "Marks": 88 }
... ]
... });
{ "acknowledged" : true, "insertedId" : ObjectId("5e2d6d24b8903cdd865577af") }
แสดงข้อมูลก่อนอัปเดต
> db.demo97.find();
ผลลัพธ์:
{ "_id" : ObjectId("5e2d6d24b8903cdd865577af"), "Details" : [
{ "Name" : "Chris", "Marks" : 45 },
{ "Name" : "Bob", "Marks" : 88 }
] }
Query เพิ่มค่า Marks ให้ Bob เพิ่ม 10 คะแนน
> db.demo97.update(
... { "Details.Name": "Bob" },
... { $inc: { "Details.$.Marks" : 10 } }
... );
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
คำอธิบาย:
{"Details.Name": "Bob"}: หาเอกสารที่ array Details มี element ที่ Name="Bob"$inc: เพิ่มค่า (atomic increment)Details.$.Marks:$คือ positional operator - อ้างอิงถึง element ใน array Details ที่ตรงเงื่อนไข (ตัวที่ Name="Bob")
ผลลัพธ์หลังอัปเดต
> db.demo97.find();
ผลลัพธ์ (Bob: 88 → 98):
{ "_id" : ObjectId("5e2d6d24b8903cdd865577af"), "Details" : [
{ "Name" : "Chris", "Marks" : 45 },
{ "Name" : "Bob", "Marks" : 98 }
] }
ข้อจำกัดและวิธีแก้
$อัปเดตได้แค่ element แรก ที่ตรงเงื่อนไข- หากต้องการอัปเดตหลาย element ใน array เดียว ให้ใช้
arrayFilters(MongoDB 3.6+):
db.demo97.updateMany(
{},
{ $inc: { "Details.$[elem].Marks": 10 } },
{ arrayFilters: [ { "elem.Name": "Bob" } ] }
)
สรุป: ใช้ $inc + positional $ สำหรับ increment field ใน array element เป้าหมาย