sql >> Databasteknik >  >> NoSQL >> MongoDB

Uppdatera ett MongoDB-underdokument när det överordnade dokumentet kanske inte finns

Du har i princip 3 fall:

  1. både boken och recensionen finns. Detta är en enkel $set
  2. boken finns men inte recensionen. Detta behöver en $push
  3. boken finns inte. Detta behöver {upsert:1} och en $setOnInsert

Jag kunde inte hitta ett sätt att förena två av dessa utan att kompromissa med dataintegriteten i händelse av fel (kom ihåg att MongoDB inte har atomär transaktion).

min bästa idén är följande:

// Case 1:
db.books.update({isbn:'1234567890',
                 review: { $elemMatch: {userID: '01234'}}},
                {$set: {'review.$.rating': NEW_RATING}}
               )

// Case 2:
db.books.update({isbn:'1234567890',
                 review: { $not: { $elemMatch: {userID: '01234'}}}},
                {$push: {review: {rating: NEW_RATING, userID:'01234'}}}
               )

// Case 3:
db.books.update({isbn:'1234567890'},
                {$setOnInsert: {review: [{rating: NEW_RATING, userID:'01234'}]}},
                {upsert:1}
               )

Du kan blint köra dessa tre uppdateringar i en raw eftersom det inte finns något överlappande fall mellan dem. Det fina med saken är att alla dessa operationer är idempotenta . Så du kan applicera dem en eller flera gånger och alltid få samma resultat. Detta är särskilt viktigt vid failover. Dessutom finns det inget sätt för din DB att vara inkonsekvent eller att förlora existerande data vid fel. I värsta fall är recensionen inte uppdaterad. Äntligen bör detta garantera datakonsistens även vid samtidiga uppdateringar (dvs:i så fall kommer en uppdatering att skriva över den andra, men du bör inte ha två dokument för samma bok eller två recensioner av samma användare för samma bok).
Den senare punkten måste bekräftas eftersom det är sent här så min analys kan vara något tveksam.

Som sista anmärkning, om du vill minska antalet tur- och returresor mellan MongoDB och din app, kan du ta en titt på update databaskommando så att du kan slå flera uppdateringar i ett kommando.




  1. Anpassad deserialisering

  2. Mongodb MapReducera prestanda med hjälp av index

  3. mina redis-nycklar upphör inte att gälla

  4. Mongodb varva ner kapslade dokument