Podobné jako vaše předchozí otázka
, používáte .bulkWrite()
ale protože výběr prvku pole má "více podmínek", zde použijete $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
}}
])
Operace jsou tedy:
-
Otestujte, zda podmínky shody prvků pole v
$elemMatch
je přítomen a poté$set
odpovídající hodnotu. -
Otestujte, že prvek pole je
$not
přítomný v negaci. Alternativně můžete použít$ne
na každé vlastnosti, ale negování podmínky, kdy se obě shodují, je o něco čistší."$elemMatch": { "weight": { "$ne": "40" }, "size": { "$ne": "40" } }
V každém případě
$push
nový prvek pole, když ne vyhovující zadaným kritériím. -
Pokuste se o "upsert" pouze tam, kde je primární dokument
_id
nebyl nalezen a použijte$setOnInsert
takže pokud je dokument nalezen, tato operace nic neprovede.
Stejně jako předtím, pouze jeden z nich skutečně něco zapíše, přestože je celá dávka odeslána na server.