MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Insérer un tableau où l'élément n'existe pas, sinon le mettre à jour (avec plusieurs conditions)

Semblable à votre question précédente , vous utilisez .bulkWrite() mais comme la sélection d'éléments de tableau a "plusieurs conditions", c'est là que vous utilisez $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
  }}
])

Donc les opérations sont :

  1. Testez que l'élément de tableau correspond aux conditions dans $elemMatch est présent, puis $set la valeur correspondante.

  2. Testez l'élément de tableau est $not présent dans la négation. Vous pouvez également utiliser $ne sur chaque propriété, mais en annulant la condition où les deux correspondent est un peu plus propre.

     "$elemMatch": { "weight": { "$ne": "40" }, "size": { "$ne": "40" } }
    

    Dans tous les cas, vous $push le nouvel élément du tableau quand on pas correspondant aux critères fournis est trouvé.

  3. Tenter un "upsert" uniquement lorsque le document principal _id est introuvable et utilisez $setOnInsert de sorte que si le document est trouvé cette opération ne fait rien.

Comme avant, un seul d'entre eux écrira quoi que ce soit malgré l'envoi de l'ensemble du lot au serveur.