Vergelijkbaar met je vorige vraag
, gebruik je .bulkWrite()
maar aangezien de selectie van het array-element "meerdere voorwaarden" heeft, gebruikt u hier $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
}}
])
Dus de bewerkingen zijn:
-
Test of het array-element overeenkomt met voorwaarden in
$elemMatchaanwezig is en dan$setde overeenkomende waarde. -
Test het array-element is
$notaanwezig in ontkenning. U kunt ook$negebruiken op elk eigendom, maar het negeren van de toestand waarin beide overeenkomen is een beetje schoner."$elemMatch": { "weight": { "$ne": "40" }, "size": { "$ne": "40" } }In ieder geval
$pushhet nieuwe array-element wanneer een niet overeenkomend met de opgegeven criteria is gevonden. -
Probeer alleen een "upsert" waar het primaire document
_idwordt niet gevonden, en gebruik$setOnInsertzodat als het document wordt gevonden, deze bewerking niets doet.
Hetzelfde als voorheen, slechts één van deze zal daadwerkelijk iets schrijven, ondanks dat de hele batch naar de server wordt verzonden.