sql >> Base de Datos >  >> NoSQL >> MongoDB

Actualice un subdocumento de MongoDB cuando el documento principal no exista

Básicamente tienes 3 casos:

  1. tanto el libro como la reseña existen. Este es un simple $set
  2. el libro existe, pero no la reseña. Esto necesita un $push
  3. el libro no existe. Esto necesita {upsert:1} y un $setOnInsert

No pude encontrar una manera de unificar dos de estos sin comprometer la integridad de los datos en caso de falla (recuerde que MongoDB no tiene transacciones atómicas).

Así que mi la mejor idea es la siguiente:

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

Puede ejecutar ciegamente esas tres actualizaciones sin procesar, ya que no hay casos superpuestos entre ellos. La belleza de la cosa es que todas estas operaciones son idempotentes . Así que puedes aplicarlos una o varias veces y obtener siempre el mismo resultado. Esto es especialmente importante en caso de conmutación por error. Además, no hay forma de que su base de datos sea inconsistente o pierda existente datos en caso de falla. En el peor de los casos, la revisión no actualizado. Finalmente esto debería garantice la consistencia de los datos incluso en el caso de actualizaciones simultáneas (es decir, en ese caso, una actualización sobrescribirá a la otra, pero no debería terminar teniendo dos documentos para el mismo libro o dos reseñas del mismo usuario para el mismo libro).
Ese último punto debe confirmarse ya que aquí es tarde, por lo que mi análisis puede ser algo dudoso.

Como nota final, si desea reducir la cantidad de viajes de ida y vuelta entre MongoDB y su aplicación, puede consultar update comando de base de datos permitiéndole envolver varias actualizaciones en un solo comando.