mongo更新阵列元素和比赛条件?

时间:2012-02-24 19:39:34

标签: mongodb spring-data

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

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

但如果 bar 首先完成,则索引已更改,而 foo comments.2.value将不再影响第三条评论。

这种情况是否可行,如果是,我想知道阵列元素更新和比赛条件是否有通用解决方案?

谢谢!

1 个答案:

答案 0 :(得分: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的评论,但我们不一定知道它会出现在数组的第二位,我们可以像这样更新它:

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

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

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

希望这可以让您了解应用程序如何修改数组中的值而无需参考其位置。祝你好运!