MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Atualizar um subdocumento do MongoDB quando o documento pai pode não existir


Basicamente você tem 3 casos:
  1. o livro e a resenha existem. Este é um simples $set
  2. o livro existe, mas não a resenha. Isso precisa de um $push
  3. o livro não existe. Isso precisa de {upsert:1} e um $setOnInsert

Não consegui encontrar uma maneira de unificar dois deles sem comprometer a integridade dos dados em caso de falha (lembre-se que o MongoDB não possui transação atômica).

Então meu melhor ideia é a seguinte:
// 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}
               )

Você pode executar cegamente essas três atualizações em um raw, pois não há sobreposição de maiúsculas e minúsculas entre elas. A beleza da coisa é que todas essas operações são idempotence . Assim, você pode aplicá-los uma ou várias vezes e obter sempre o mesmo resultado. Isso é especialmente importante em caso de failover. Além disso, não há como seu banco de dados ser inconsistente ou perder o existente dados em caso de falha. Na pior das hipóteses, a avaliação não Atualizada. Finalmente, isso deve garantir a consistência dos dados mesmo em caso de atualizações simultâneas (ou seja:nesse caso, uma atualização substituirá a outra, mas você não deve acabar tendo dois documentos para o mesmo livro ou duas resenhas do mesmo usuário para o mesmo livro).
Esse ponto posterior precisa ser confirmado, pois é tarde aqui, então minha análise pode ser um pouco duvidosa.

Como nota final, se você quiser reduzir o número de viagens de ida e volta entre o MongoDB e seu aplicativo, você pode dar uma olhada no update comando de banco de dados permitindo que você envolva várias atualizações em um comando.