sql >> Database teknologi >  >> NoSQL >> MongoDB

Opdater Array, hvor det findes, eller Indsæt nyt Array-element

Du vil have .bulkWrite() for det. Dette er faktisk ikke en enkelt operation, så du ønsker at indsende flere operationer i en enkelt anmodning. Forsøg i det væsentlige at skrive opdateringen med $set hvor data findes eller $push de nye data, hvor de ikke findes:

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

Det positive tilfælde er simpelthen værdien og $ne "negerer" lighedsmatchet, hvilket betyder, at varen ikke eksisterer. Selvfølgelig positionelle $ operatør bruges sammen med $set hvor det gør

Givet dataene vil kun én af operationerne faktisk matche og gælde som en opdatering på trods af at to operationer sendes i "batchen".

Hvis du også vil have "upserts" for hele dokumentet, så skal du tilføje en anden operation til slutningen af ​​det. Bemærk, at du ikke kan anvende "upsert" som en mulighed på nogen af ​​de andre udsagn, især $ne fordi det ville skabe et nyt dokument, hvor array-elementet ikke eksisterer, ikke kun _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
  }}
])

$setOnInsert er den vigtigste hjælp her, bortset fra at den sidste operation er den eneste markeret som "upsert" . Denne kombination sikrer, at der, hvor det primære "dokument" er fundet, så sker der faktisk ikke noget, men når det ikke findes, tilføjes det nye array-element.

Som en sidebemærkning vil jeg kraftigt foreslå at gemme numeriske værdier faktisk som numeriske snarere end strenge. Det sparer ikke kun plads i de fleste tilfælde, men det er også langt mere nyttigt på den måde.




  1. Inkrementelt felt til eksisterende samling

  2. Guide til Upsert i MongoDB

  3. StackExchange.Redis timeout

  4. Hvordan indstiller jeg en elasticache redis klynge som slave?