Tương tự với câu hỏi trước của bạn
, bạn sử dụng .bulkWrite()
nhưng vì lựa chọn phần tử mảng có "nhiều điều kiện" nên đây là nơi bạn sử dụng $elemMatch
:
db.collection.bulkWrite([
{ "updateOne": {
"filter": {
"_id": "1",
"option": {
"$elemMatch": { "weight": "40", "size": "40" }
}
},
"update": {
"$set": { "option.$.price": "300" }
}
}},
{ "updateOne": {
"filter": {
"_id": "1",
"option": {
"$not": {
"$elemMatch": { "weight": "40", "size": "40" }
}
}
},
"update": {
"$push": { "option": { "weight": "40", "size": "40", "price": "300" } }
}
}},
{ "updateOne": {
"filter": { "_id": 1 },
"update": {
"$setOnInsert": {
"option": [
{ "weight": "40", "size": "40", "price": "300" }
]
}
},
"upsert": true
}}
])
Vì vậy, các hoạt động là:
-
Kiểm tra xem các điều kiện khớp với phần tử mảng trong
$elemMatch
hiện tại và sau đó$set
giá trị phù hợp. -
Kiểm tra phần tử mảng là
$not
hiện diện trong phủ định. Bạn có thể luân phiên sử dụng$ne
trên mỗi thuộc tính, nhưng phủ định điều kiện mà cả hai đối sánh thì rõ ràng hơn một chút."$elemMatch": { "weight": { "$ne": "40" }, "size": { "$ne": "40" } }
Ở bất kỳ mức giá nào, bạn
$push
phần tử mảng mới khi một không phù hợp với các tiêu chí được cung cấp được tìm thấy. -
Chỉ thử "upert" khi tài liệu chính
_id
không được tìm thấy và sử dụng$setOnInsert
để nếu tài liệu được tìm thấy thì thao tác này sẽ không làm gì cả.
Giống như trước đây, chỉ một trong số này sẽ thực sự viết bất kỳ thứ gì mặc dù toàn bộ lô được gửi đến máy chủ.