sql >> Databasteknik >  >> NoSQL >> MongoDB

Uppdatera Array där den finns eller Infoga nytt Array-objekt

Du vill ha .bulkWrite() för detta. Detta är faktiskt inte en enda operation, så du vill skicka flera operationer i en enda begäran. Försök att skriva uppdateringen med $set där data finns eller $push den nya data där den inte finns:

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 positiva fallet är helt enkelt värdet och $ne "negerer" jämställdhetsmatchningen, vilket betyder att föremålet inte existerar. Naturligtvis positionella $ operatör används med $set där det gör

Med tanke på data kommer endast en av operationerna faktiskt att matcha och tillämpas som en uppdatering trots att två operationer skickas i "batchen".

Om du vill ha "upserts" för hela dokumentet också, måste du lägga till en annan operation i slutet av det. Observera att du inte kan använda "upsert" som ett alternativ på något av de andra påståendena, särskilt $ne eftersom det skulle skapa ett nytt dokument där arrayobjektet inte finns, inte bara _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 är den viktigaste hjälpen här förutom att den sista operationen är den enda som är markerad som "upsert" . Den kombinationen säkerställer att där det primära "dokumentet" hittas händer ingenting, men när det inte hittas läggs det nya arrayobjektet till.

Som en sidoanteckning skulle jag starkt rekommendera att lagra numeriska värden faktiskt som numeriska snarare än strängar. Det sparar inte bara utrymme i de flesta fall utan det är också mycket mer användbart på det sättet.




  1. fel vid anslutning till värd:kunde inte ansluta till server:servervalsfel:serverval timeout aktuell topologi:Typ:Singelservrar

  2. Lyssna på återanslutningshändelser i MongoDB-drivrutinen

  3. Testa tom sträng i mongodb och pymongo

  4. MongoDB $replaceAll