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
$elemMatch
aanwezig is en dan$set
de overeenkomende waarde. -
Test het array-element is
$not
aanwezig in ontkenning. U kunt ook$ne
gebruiken 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
$push
het nieuwe array-element wanneer een niet overeenkomend met de opgegeven criteria is gevonden. -
Probeer alleen een "upsert" waar het primaire document
_id
wordt niet gevonden, en gebruik$setOnInsert
zodat 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.