MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Insira a matriz onde o elemento não existe mais atualize-o (com várias condições)


Semelhante a sua pergunta anterior , você usa .bulkWrite() mas como a seleção do elemento da matriz tem "múltiplas condições", é aqui que você 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
  }}
])

Então as operações são:

  1. Teste as condições de correspondência do elemento da matriz em $elemMatch está presente e, em seguida, $set o valor correspondido.

  2. Teste se o elemento da matriz é $not presente na negação. Você pode usar alternativamente $ne em cada propriedade, mas negando a condição em que ambas as correspondências são um pouco mais limpas.
     "$elemMatch": { "weight": { "$ne": "40" }, "size": { "$ne": "40" } }
    

    De qualquer forma, você $push o novo elemento de matriz quando um não correspondente aos critérios fornecidos é encontrado.

  3. Tente um "upsert" somente onde o documento principal _id não foi encontrado e use $setOnInsert para que, se o documento for encontrado, essa operação não faça nada.

Da mesma forma que antes, apenas um deles realmente escreverá alguma coisa, apesar de todo o lote ser enviado ao servidor.