Pregunta

estoy imaginando foo está actualizando el tercer comentario, comments.2.value, mientras bar es $pull-ing, eliminando el primer comentario.

Si foo termina primero, luego el tercer comentario se actualiza exitosamente, ya que el índice aún es correcto.

Pero si bar termina primero, luego el índice ha cambiado y foo's comments.2.value Ya no afectaría al tercer comentario.

¿Es este escenario posible y, si lo es, me pregunto si existen soluciones comunes para las actualizaciones de elementos de la matriz y las condiciones de carrera?

Gracias !

¿Fue útil?

Solución

La situación que describió es teóricamente posible si varias aplicaciones acceden a la base de datos simultáneamente.Por esta razón, es mejor, si es posible, darle a cada miembro de la matriz algún identificador único, en lugar de acceder a los elementos de la matriz por posición.

Por ejemplo,

> db.myComments.save({_id:1,
comments:[
{cid:1, author:"Marc", comment:"Marc's Comment"}, 
{cid:2, author:"Mike", comment:"Mike's Comment"}, 
{cid:3, author:"Barrie", comment:"Barrie's Comment"}
]})

Si queremos modificar el comentario de Mike, pero no necesariamente sabemos que aparecerá en segundo lugar en la matriz, podemos actualizarlo así:

> db.myComments.update({_id:1, "comments.cid":2}, {$set:{"comments.$.comment":"Mike's NEW Comment"}})
> db.myComments.find().pretty()
{
    "_id" : 1,
    "comments" : [
        {
            "cid" : 1,
            "author" : "Marc",
            "comment" : "Marc's Comment"
        },
        {
            "author" : "Mike",
            "cid" : 2,
            "comment" : "Mike's NEW Comment"
        },
        {
            "cid" : 3,
            "author" : "Barrie",
            "comment" : "Barrie's Comment"
        }
    ]
}

Incluso podríamos cambiar todo el subdocumento, así:

> db.myComments.update({_id:1, "comments.cid":2}, {$set:{"comments.$":{cid:4, author:"someone else", comment:"A completely new comment!"}}})
> db.myComments.find().pretty()
{
    "_id" : 1,
    "comments" : [
        {
            "cid" : 1,
            "author" : "Marc",
            "comment" : "Marc's Comment"
        },
        {
            "cid" : 4,
            "author" : "someone else",
            "comment" : "A completely new comment!"
        },
        {
            "cid" : 3,
            "author" : "Barrie",
            "comment" : "Barrie's Comment"
        }
    ]
}

El documento de consulta encontrará el primer valor en la matriz que coincida, y el "$" en el documento de actualización hace referencia a esa posición.

Puede encontrar más información sobre el operador "$" en la sección "El operador posicional $" de la documentación "Actualización".http://www.mongodb.org/display/DOCS/Updating#Updating-The%24positionaloperator

Con suerte, esto le dará una idea de cómo su aplicación puede modificar valores en una matriz sin hacer referencia a su posición.¡Buena suerte!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top