Подобно на предишния ви въпрос
, използвате .bulkWrite()
но тъй като изборът на елемент от масива има "множество условия", тук използвате $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
}}
])
Така че операциите са:
-
Тествайте дали елементът на масива отговаря на условията в
$elemMatch
присъства и след това$set
съответстващата стойност. -
Тествайте елемента на масива е
$not
присъства в отрицание. Можете алтернативно да използвате$ne
на всяко свойство, но отричането на условието, при което и двете съвпадат, е малко по-чисто."$elemMatch": { "weight": { "$ne": "40" }, "size": { "$ne": "40" } }
Във всеки случай вие
$push
новият елемент на масива, когато единне съответстващ на предоставените критерии. -
Опитайте „upsert“ само там, където основният документ
_id
не е намерен и използвайте$setOnInsert
така че ако документът бъде намерен, тази операция не прави нищо.
Както и преди, само един от тях действително ще напише нещо, въпреки че целият пакет е изпратен до сървъра.