Liknar din tidigare fråga
, använder du .bulkWrite()
men eftersom valet av arrayelement har "flera villkor" är det här du använder $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å operationerna är:
-
Testa att arrayelementet matchar villkoren i
$elemMatch
är närvarande och sedan$set
det matchade värdet. -
Testa arrayelementet är
$not
närvarande i negation. Du kan alternativt använda$ne
på varje fastighet, men förnekar villkoret där båda matchar är lite renare."$elemMatch": { "weight": { "$ne": "40" }, "size": { "$ne": "40" } }
Du
$push
det nya arrayelementet när ett inte som matchar de angivna kriterierna hittas. -
Försök en "upsert" endast där det primära dokumentet
_id
hittas inte och använd$setOnInsert
så att om dokumentet hittas gör denna operation ingenting.
Samma som tidigare, bara en av dessa kommer faktiskt att skriva något trots att hela batchen skickas till servern.