Tất nhiên những gì bạn đang làm ở đây thực sự là kiểm tra phản hồi cho biết liệu một tài liệu đã được cập nhật hay được chèn vào hay thực tế nếu cả hai thao tác đều không xảy ra. Đó là chỉ báo tốt nhất của bạn đối với $addToSet
để thực hiện cập nhật, tài liệu sau đó sẽ được cập nhật.
$addToSet
bản thân toán tử không thể tạo ra các bản sao, đó là bản chất của toán tử. Nhưng bạn thực sự có thể gặp một số vấn đề với logic của mình:
{
"$addToSet", new BsonDocument()
{
{ "items", new BsonDocument()
{
{ "id", item.Id },
{ "v", item.Value }
}
}
}
}
Vì vậy, rõ ràng là bạn đang cho thấy rằng một mục trong "tập hợp" của bạn bao gồm hai trường, vì vậy nếu nội dung đó khác nhau theo bất kỳ cách nào (tức là cùng một id nhưng khác giá trị) thì mục thực sự là thành viên "duy nhất" của tập hợp và sẽ được thêm. Chẳng hạn như sẽ không có cách nào cho $addToSet
toán tử để không thêm các giá trị mới hoàn toàn dựa trên "id" làm số nhận dạng duy nhất. Bạn sẽ phải thực sự cuộn nó trong mã.
Khả năng thứ hai ở đây đối với một dạng trùng lặp là phần truy vấn của bạn không tìm thấy chính xác tài liệu cần được cập nhật. Kết quả của việc này sẽ là tạo ra một tài liệu mới chỉ chứa thành viên mới được chỉ định trong "tập hợp". Vì vậy, một lỗi sử dụng phổ biến là như sau:
db.collection.update(
{
"id": ABC,
"items": { "$elemMatch": {
"id": 123, "v": 10
}},
{
"$addToSet": {
"items": {
"id": 123, "v": 10
}
}
},
{ "upsert": true }
)
Kết quả của thao tác sắp xếp đó sẽ luôn tạo ra một tài liệu mới vì tài liệu hiện có không chứa phần tử được chỉ định trong "tập hợp". Cách triển khai đúng là không kiểm tra sự hiện diện của thành viên "set" và cho phép $addToSet
để thực hiện công việc.
Nếu thực sự bạn có đúng các mục nhập trùng lặp xảy ra trong "tập hợp" nơi tất cả các phần tử của tài liệu con hoàn toàn giống nhau, thì nguyên nhân là do một số mã khác hiện tại hoặc trong quá khứ gây ra.
Khi bạn chắc chắn rằng có một mục nhập mới đang được tạo, hãy xem qua mã để biết các trường hợp của $push
hoặc thực sự và thao tác mảng trong mã dường như đang hoạt động trên cùng một trường.
Nhưng nếu bạn đang sử dụng đúng toán tử thì $addToSet
thực hiện chính xác những gì nó dự định làm.