【问题标题】:mongo updating array element and racing condition?mongo 更新数组元素和赛车条件?
【发布时间】:2012-02-24 19:39:34
【问题描述】:

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

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

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

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

谢谢!

【问题讨论】:

    标签: mongodb spring-data


    【解决方案1】:

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

    例如,

    > 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

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

    【讨论】:

    • 太棒了!现在我真的可以再次睡个好觉了。我想知道theoretically possible if multiple applications are accessing the database simultaneously 是什么意思,因为就我而言,我只有一个应用程序,但有多个并发用户。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-05
    • 1970-01-01
    • 2021-06-02
    • 2015-03-29
    • 1970-01-01
    • 2018-08-12
    • 2023-03-07
    相关资源
    最近更新 更多