0

我想象foo正在更新第三条评论comments.2.value,而bar正在$pull删除第一条评论。

如果foo先完成,则第三条评论更新成功,因为索引仍然正确。

但是如果bar首先完成,那么索引已经改变,并且foocomments.2.value将不再影响第三条评论。

这种情况是否可能,如果是,我想知道数组元素更新和赛车条件是否有通用解决方案?

谢谢 !

4

1 回答 1

3

如果多个应用程序同时访问数据库,您描述的情况在理论上是可能的。出于这个原因,如果可能的话,最好给数组的每个成员一个唯一的标识符,而不是按位置访问数组中的元素。

例如,

> 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"}
]})

如果我们想修改 Mike 的 Comment,但我们不一定知道它会出现在数组中的第二个,我们可以像这样更新它:

> 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"
        }
    ]
}

我们甚至可以更改整个子文档,如下所示:

> 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"
        }
    ]
}

查询文档将在数组中找到第一个匹配的值,更新文档中的“$”引用该位置。

有关“$”运算符的更多信息,请参见“更新”文档的“$ 位置运算符”部分。 http://www.mongodb.org/display/DOCS/Updating#Updating-The%24positionaloperator

希望这能让您了解您的应用程序如何在不引用其位置的情况下修改数组中的值。祝你好运!

于 2012-02-24T20:14:20.457 回答