Podobne do Twojego poprzedniego pytania
, używasz .bulkWrite()
ale ponieważ wybór elementu tablicy ma „wiele warunków”, tutaj używasz $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
}}
])
Czyli operacje są następujące:
-
Sprawdź, czy element tablicy pasuje do warunków w
$elemMatch
jest obecny, a następnie$set
dopasowana wartość. -
Przetestuj element tablicy to
$not
obecny w negacji. Możesz alternatywnie użyć$ne
na każdej właściwości, ale negowanie warunku, w którym oba dopasowania są nieco bardziej przejrzyste."$elemMatch": { "weight": { "$ne": "40" }, "size": { "$ne": "40" } }
W każdym razie
$push
nowy element tablicy, gdy nie spełniające podane kryteria. -
Próbuj "upsert" tylko wtedy, gdy dokument główny
_id
nie został znaleziony i użyj$setOnInsert
więc jeśli dokument zostanie znaleziony, ta operacja nic nie da.
Tak jak poprzednio, tylko jeden z nich zapisze wszystko, mimo że cała partia jest wysyłana na serwer.