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

Actualizar matriz donde exista o insertar nuevo elemento de matriz

Quiere .bulkWrite() para esto. En realidad, esta no es una sola operación, por lo que desea enviar varias operaciones en una sola solicitud. Básicamente intenta escribir la actualización con $set donde existen datos o $push los nuevos datos donde no existen:

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" } }
    }
  }}
])

El caso positivo es simplemente el valor, y el $ne "niega" la coincidencia de igualdad, lo que significa que el elemento no existe. Por supuesto, el posicional $ operador se usa con $set donde lo hace

Dados los datos, solo una de las operaciones coincidirá y se aplicará como una actualización a pesar de que se envíen dos operaciones en el "lote".

Si también desea "upserts" para todo el documento, debe agregar otra operación al final de eso. Tenga en cuenta que no puede aplicar "upsert" como una opción en ninguna de las otras declaraciones, especialmente $ne porque eso crearía un nuevo documento donde el elemento de la matriz no existe, no solo el _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
  }}
])

El $setOnInsert es la ayuda principal aquí aparte de que la última operación es la única marcada como "upsert" . Esa combinación asegura que donde se encuentra el "documento" principal, en realidad no sucede nada, pero cuando no se encuentra, se agrega el nuevo elemento de matriz.

Como nota al margen, recomendaría encarecidamente almacenar valores numéricos en realidad como numéricos en lugar de cadenas. No solo ahorra espacio en la mayoría de los casos, sino que también es mucho más útil de esa manera.