Ähnlich wie bei Ihrer vorherigen Frage
verwenden Sie .bulkWrite()
aber da die Array-Elementauswahl "mehrere Bedingungen" hat, verwenden Sie 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
}}
])
Die Operationen sind also:
-
Testen Sie, ob die Array-Element-Übereinstimmungsbedingungen in
$elemMatchvorhanden ist und dann$setder übereinstimmende Wert. -
Testen Sie, dass das Array-Element
$notist in Verneinung vorhanden. Alternativ können Sie$neverwenden auf jeder Eigenschaft, aber das Negieren der Bedingung, in der beide übereinstimmen, ist etwas sauberer."$elemMatch": { "weight": { "$ne": "40" }, "size": { "$ne": "40" } }Auf jeden Fall
$pushdas neue Array-Element, wenn man nicht Übereinstimmung mit den angegebenen Kriterien gefunden. -
Versuchen Sie ein "Upsert" nur dort, wo das primäre Dokument
_idist nicht gefunden wird, und verwenden Sie$setOnInsertso dass diese Operation nichts bewirkt, wenn das Dokument gefunden wird.
Wie zuvor wird nur einer von ihnen tatsächlich etwas schreiben, obwohl der gesamte Stapel an den Server gesendet wird.