sql >> Database >  >> NoSQL >> MongoDB

Update array waar het bestaat of voeg nieuw array-item in

U wilt .bulkWrite() voor deze. Dit is eigenlijk geen enkele bewerking, dus u wilt meerdere bewerkingen in één verzoek indienen. Probeer in wezen de update te schrijven met $set waar gegevens bestaan ​​of $push de nieuwe gegevens waar ze niet bestaan:

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

Het positieve geval is gewoon de waarde, en de $ne "negeert" de gelijkheidsovereenkomst, wat betekent dat het item niet bestaat. Natuurlijk de positionele $ operator wordt gebruikt met $set waar het doet

Gezien de gegevens zal slechts één van de bewerkingen daadwerkelijk overeenkomen en als een update worden toegepast, ondanks dat er twee bewerkingen in de "batch" worden verzonden.

Als je ook "upserts" voor het hele document wilt, dan moet je daar nog een bewerking aan toevoegen. Merk op dat u "upsert" niet als optie kunt toepassen op een van de andere instructies, met name de $ne omdat dat een nieuw document zou creëren waarin het array-item niet bestaat, niet alleen de _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
  }}
])

De $setOnInsert is de belangrijkste hulp hier, behalve dat die laatste bewerking de enige is die is gemarkeerd als "upsert" . Die combinatie zorgt ervoor dat waar het primaire "document" wordt gevonden, er niets gebeurt, maar wanneer het niet wordt gevonden, wordt het nieuwe array-item toegevoegd.

Als een kanttekening zou ik sterk aanbevelen om numerieke waarden eigenlijk als numeriek op te slaan in plaats van strings. Het bespaart in de meeste gevallen niet alleen ruimte, maar is op die manier ook veel nuttiger.




  1. Databases die JSON gebruiken als opslag-/transportformaat

  2. Hetzelfde document parallel opvragen in dezelfde API in mongoDB

  3. Moet ik een schaarse index gebruiken voor booleaanse vlaggen in mongodb?

  4. Snelste manier om 100 miljoen documenten op ID te verwijderen