บทความนี้สาธิตการเพิ่มข้อมูลเข้า Array ที่อยู่ภายใน Object ซึ่งอยู่ใน Array อีกทีหนึ่ง (Nested Array) โดยใช้ $addToSet ร่วมกับ Positional Operator $
สร้างข้อมูลตัวอย่าง
> db.insertDataIntoArrayDemo.insertOne(
{
"UserDetails":[
{ "UserId" : "user121", "userGroupMessage": [] },
{ "UserId" : "user221", "userGroupMessage": ["Cool", "Good Morning"] }
]
}
);
{ "acknowledged" : true, "insertedId" : ObjectId("5cd694e157806ebf1256f128") }
แสดงข้อมูลก่อนเพิ่ม
> db.insertDataIntoArrayDemo.find().pretty();
{
"_id" : ObjectId("5cd694e157806ebf1256f128"),
"UserDetails" : [
{ "UserId" : "user121", "userGroupMessage" : [ ] },
{ "UserId" : "user221", "userGroupMessage" : [ "Cool", "Good Morning" ] }
]
}
เพิ่ม "Hello" เข้า userGroupMessage ของ UserId = "user121"
> db.insertDataIntoArrayDemo.update(
{ "UserDetails.UserId": "user121" },
{ "$addToSet": { "UserDetails.$.userGroupMessage": "Hello" } }
);
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
ตรวจสอบผลลัพธ์
> db.insertDataIntoArrayDemo.find().pretty();
{
"_id" : ObjectId("5cd694e157806ebf1256f128"),
"UserDetails" : [
{ "UserId" : "user121", "userGroupMessage" : [ "Hello" ] },
{ "UserId" : "user221", "userGroupMessage" : [ "Cool", "Good Morning" ] }
]
}
คำอธิบายการทำงาน
- Query:
{ "UserDetails.UserId": "user121" }- หา Document ที่ Array UserDetails มี Element ที่ UserId = "user121" - Positional $:
UserDetails.$.userGroupMessage- อ้างอิงถึง Element แรกใน Array UserDetails ที่ Match Query - $addToSet: เพิ่ม "Hello" เข้า Array userGroupMessage (ไม่ซ้ำ)
ข้อจำกัดของ Positional Operator $
- อัปเดตได้ Element แรกเท่านั้น ที่ Match Query
- ไม่สามารถอัปเดตหลาย Element ใน Array เดียวกันได้ในครั้งเดียว
- ใช้กับ Nested Array ได้เพียง 1 ระดับ (ไม่รองรับ $ ซ้อน)
วิธีทันสมัย (MongoDB 3.6+): ใช้ arrayFilters
db.insertDataIntoArrayDemo.updateOne(
{ },
{ $addToSet: { "UserDetails.$[elem].userGroupMessage": "Hello" } },
{ arrayFilters: [{ "elem.UserId": "user121" }] }
);
วิธีนี้ชัดเจนกว่า รองรับหลาย Element และ Nested Array ได้ดีกว่า