sql >> Base de Datos >  >> NoSQL >> MongoDB

Inserte una matriz donde el elemento no existe; de ​​lo contrario, actualícelo (con múltiples condiciones)

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:

  1. Pruebe que el elemento de la matriz coincida con las condiciones en $elemMatch está presente y luego $set el valor coincidente.

  2. 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.

  3. 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.