Svarer til dit tidligere spørgsmål
, bruger du .bulkWrite()
men da array-elementvalget har "flere betingelser", er det her du bruger $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
}}
])
Så operationerne er:
-
Test, at array-elementet matcher betingelserne i
$elemMatch
er til stede og derefter$set
den matchede værdi. -
Test array-elementet er
$not
til stede i negation. Du kan alternativt bruge$ne
på hver ejendom, men ophæver tilstanden, hvor begge matcher er en smule renere."$elemMatch": { "weight": { "$ne": "40" }, "size": { "$ne": "40" } }
I hvert fald
$push
det nye array-element, når man ikke der matcher de angivne kriterier er fundet. -
Forsøg kun en "upsert" hvor det primære dokument
_id
er ikke fundet, og brug$setOnInsert
så hvis dokumentet er fundet, gør denne handling intet.
Samme som før, kun én af disse vil faktisk skrive noget på trods af at hele batchen sendes til serveren.