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

Aggiorna un documento secondario MongoDB quando il documento padre potrebbe non esistere

Fondamentalmente hai 3 casi:

  1. sia il libro che la recensione esistono. Questo è un semplice $set
  2. il libro esiste ma non la recensione. Questo richiede un $push
  3. il libro non esiste. Questo richiede {upsert:1} e un $setOnInsert

Non sono riuscito a trovare un modo per unificare due di questi senza compromettere l'integrità dei dati in caso di errore (ricorda che MongoDB non ha una transazione atomica).

Quindi mio la migliore idea è la seguente:

// 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}
               )

Puoi eseguire alla cieca questi tre aggiornamenti in un raw poiché non ci sono casi sovrapposti tra di loro. Il bello è che tutte queste operazioni sono idempotent . Quindi puoi applicarli una o più volte e ottenere sempre lo stesso risultato. Ciò è particolarmente importante in caso di failover. Inoltre, non c'è modo che il tuo DB sia incoerente o perda esistente dati in caso di guasto. Nel peggiore dei casi, la recensione non aggiornato. Infine questo dovrebbe garantire la coerenza dei dati anche in caso di aggiornamenti simultanei (es.:in tal caso, un aggiornamento sovrascriverà l'altro, ma non dovresti avere due documenti per lo stesso libro o due recensioni dello stesso utente per lo stesso libro).
Questo punto successivo deve essere confermato poiché qui è tardi, quindi la mia analisi potrebbe essere alquanto dubbia.

Come nota finale, se desideri ridurre il numero di viaggi di andata e ritorno tra MongoDB e la tua app, potresti dare un'occhiata a update comando database permettendoti di racchiudere diversi aggiornamenti in un unico comando.