Để thêm phần tử vào mảng nằm bên trong đối tượng (embedded document) trong mảng, MongoDB sử dụng toán tử $addToSet (hoặc $push) kết hợp với positional operator $ để xác định đối tượng cha trong mảng ngoài.
Tạo dữ liệu mẫu
> db.insertDataIntoArrayDemo.insertOne(
{
"UserDetails":[
{ "UserId" :"user121", "userGroupMessage":[] },
{ "UserId" :"user221", "userGroupMessage":["Cool","Good Morning"] }
]
}
);
{ "acknowledged" : true, "insertedId" : ObjectId("5cd694e157806ebf1256f128") }
Xem dữ liệu ban đầu
> db.insertDataIntoArrayDemo.find().pretty();
Thêm tin nhắn cho user121
> db.insertDataIntoArrayDemo.update( {"UserDetails.UserId":"user121"}, {"$addToSet":{"UserDetails.$.userGroupMessage":"Hello"}} ); WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })Kết quả
> db.insertDataIntoArrayDemo.find().pretty();Giải thích cơ chế
{"UserDetails.UserId":"user121"}: Tìm tài liệu có phần tử trong mảng UserDetails thỏa mãn UserId = "user121"UserDetails.$.userGroupMessage: Toán tử$tham chiếu đến phần tử đầu tiên trong mảng UserDetails khớp với điều kiện truy vấn$addToSet: Thêm "Hello" vào mảng userGroupMessage nếu chưa tồn tạiLưu ý quan trọng về Positional Operator $
- Chỉ cập nhật một phần tử đầu tiên khớp
- Nếu có nhiều user121 trong mảng, chỉ cái đầu được cập nhật
- Không hoạt động với nested array sâu hơn 1 cấp (cần arrayFilters)
Cách hiện đại: arrayFilters (MongoDB 3.6+)
Hỗ trợ cập nhật nhiều phần tử, mảng lồng sâu, logic phức tạp:
db.insertDataIntoArrayDemo.updateMany(
{},
{$addToSet: {"UserDetails.$[user].userGroupMessage": "Hello"}},
{arrayFilters: [{"user.UserId": "user121"}]}
);
Thêm nhiều tin nhắn cùng lúc
db.insertDataIntoArrayDemo.update(
{"UserDetails.UserId":"user121"},
{$addToSet: {"UserDetails.$.userGroupMessage": {$each: ["Hello", "Hi", "Hey"]}}}
);
So sánh $addToSet vs $push
$addToSet: Không thêm nếu đã tồn tại (unique)$push: Luôn thêm, cho phép trùng lặp