Similar a su pregunta anterior
, utiliza .bulkWrite()
pero dado que la selección del elemento de matriz tiene "múltiples condiciones", aquí es donde usa $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
}}
])
Entonces las operaciones son:
-
Pruebe que el elemento de la matriz coincida con las condiciones en
$elemMatch
está presente y luego$set
el valor coincidente. -
Pruebe que el elemento de la matriz es
$not
presente en la negación. Alternativamente, podría usar$ne
en cada propiedad, pero negando la condición donde ambos coinciden es un poco más limpio."$elemMatch": { "weight": { "$ne": "40" }, "size": { "$ne": "40" } }
En cualquier caso,
$push
el nuevo elemento de matriz cuando uno no se encuentra la coincidencia con los criterios proporcionados. -
Intente un "upsert" solo donde el documento principal
_id
no se encuentra y use$setOnInsert
de manera que si se encuentra el documento esta operación no hace nada.
Igual que antes, solo uno de estos realmente escribirá algo a pesar de que todo el lote se envíe al servidor.