Du vil have .bulkWrite()
for det. Dette er faktisk ikke en enkelt operation, så du ønsker at indsende flere operationer i en enkelt anmodning. Forsøg i det væsentlige at skrive opdateringen med $set
hvor data findes eller $push
de nye data, hvor de ikke findes:
db.collection.bulkWrite([
{ "updateOne": {
"filter": { "_id": "1", "option.weight": "10" },
"update": {
"$set": { "option.$.price": "30" }
}
}},
{ "updateOne": {
"filter": { "_id": "1", "option.weight": { "$ne": "10" } },
"update": {
"$push": { "option": { "weight": "10", "price": "30" } }
}
}}
])
Det positive tilfælde er simpelthen værdien og $ne
"negerer" lighedsmatchet, hvilket betyder, at varen ikke eksisterer. Selvfølgelig positionelle $
operatør
bruges sammen med $set
hvor det gør
Givet dataene vil kun én af operationerne faktisk matche og gælde som en opdatering på trods af at to operationer sendes i "batchen".
Hvis du også vil have "upserts" for hele dokumentet, så skal du tilføje en anden operation til slutningen af det. Bemærk, at du ikke kan anvende "upsert" som en mulighed på nogen af de andre udsagn, især $ne
fordi det ville skabe et nyt dokument, hvor array-elementet ikke eksisterer, ikke kun _id
:
db.collection.bulkWrite([
{ "updateOne": {
"filter": { "_id": "1", "option.weight": "10" },
"update": {
"$set": { "option.$.price": "30" }
}
}},
{ "updateOne": {
"filter": { "_id": "1", "option.weight": { "$ne": "10" } },
"update": {
"$push": { "option": { "weight": "10", "price": "30" } }
}
}},
{ "updateOne": {
"filter": { "_id": 1 },
"update": {
"$setOnInsert": {
"option": [
{ "weight": "10", "price": "30" }
]
}
},
"upsert": true
}}
])
$setOnInsert
er den vigtigste hjælp her, bortset fra at den sidste operation er den eneste markeret som "upsert"
. Denne kombination sikrer, at der, hvor det primære "dokument" er fundet, så sker der faktisk ikke noget, men når det ikke findes, tilføjes det nye array-element.
Som en sidebemærkning vil jeg kraftigt foreslå at gemme numeriske værdier faktisk som numeriske snarere end strenge. Det sparer ikke kun plads i de fleste tilfælde, men det er også langt mere nyttigt på den måde.