MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Array einfügen, wo das Element nicht existiert, andernfalls aktualisieren (mit mehreren Bedingungen)

Ähnlich wie bei Ihrer vorherigen Frage verwenden Sie .bulkWrite() aber da die Array-Elementauswahl "mehrere Bedingungen" hat, verwenden Sie hier $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
  }}
])

Die Operationen sind also:

  1. Testen Sie, ob die Array-Element-Übereinstimmungsbedingungen in $elemMatch vorhanden ist und dann $set der übereinstimmende Wert.

  2. Testen Sie, dass das Array-Element $not ist in Verneinung vorhanden. Alternativ können Sie $ne verwenden auf jeder Eigenschaft, aber das Negieren der Bedingung, in der beide übereinstimmen, ist etwas sauberer.

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

    Auf jeden Fall $push das neue Array-Element, wenn man nicht Übereinstimmung mit den angegebenen Kriterien gefunden.

  3. Versuchen Sie ein "Upsert" nur dort, wo das primäre Dokument _id ist nicht gefunden wird, und verwenden Sie $setOnInsert so dass diese Operation nichts bewirkt, wenn das Dokument gefunden wird.

Wie zuvor wird nur einer von ihnen tatsächlich etwas schreiben, obwohl der gesamte Stapel an den Server gesendet wird.