Toán tử $addToSet thêm giá trị vào mảng nếu chưa tồn tại. Kết hợp với positional operator $ để cập nhật mảng lồng sâu.
Tạo collection với mảng rỗng lồng nhau:
> db.demo380.insertOne({
"details" : [
{ "Name" : "Chris", "details1" : [ ] },
{ "Name" : "David", "details1" : [ ] }
]
});
{ "acknowledged" : true, "insertedId" : ObjectId("5e5b56e32ae06a1609a00b11") }
Xem dữ liệu:
> db.demo380.find().pretty();
{ "_id" : ObjectId("5e5b56e32ae06a1609a00b11"), "details" : [ { "Name" : "Chris", "details1" : [ ] }, { "Name" : "David", "details1" : [ ] } ] }
Thêm đối tượng vào mảng details1 của phần tử có Name="David":
> db.demo380.update(
{ "details.Name": "David" },
{ $addToSet: { "details.$.details1": { 'SubjectName': "MongoDB", 'TeacherName':"Bob" } } },
false, true
);
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Kết quả:
> db.demo380.find().pretty();
{ "_id" : ObjectId("5e5b56e32ae06a1609a00b11"), "details" : [ { "Name" : "Chris", "details1" : [ ] }, { "Name" : "David", "details1" : [ { "SubjectName" : "MongoDB", "TeacherName" : "Bob" } ] } ] }
Phân tích:
- Query
{"details.Name": "David"}: tìm tài liệu có phần tử details.Name = "David" details.$.details1:$trỏ đến phần tử details khớp, truy cập mảng con details1$addToSet: thêm đối tượng nếu chưa có (so sánh toàn bộ đối tượng)- Tham số
false, true:upsert=false, multi=true(cập nhật tất cả khớp)
Lưu ý: $addToSet so sánh toàn bộ đối tượng. Nếu chỉ muốn unique theo một trường, dùng $addToSet với giá trị đơn giản hoặc aggregation.