【问题标题】:Update array object based on id?根据 id 更新数组对象?
【发布时间】:2012-11-28 00:15:54
【问题描述】:

我遇到了一些 mongo 问题。我想知道是否有办法在 mongo 控制台命令中执行以下操作,而不是多个 findupdate 调用。

{
    "_id" : ObjectId("50b429ba0e27b508d854483e"),
    "array" : [
        {
            "id" : "1",
            "letter" : "a"
        },
        {
            "id" : "2",
            "letter" : "b"
        }
    ],
    "tester" : "tom"
}

我想用这个新的数组项更新对象

{
    "id": "2",
    "letter": "c"
}

我使用了这个,addToSet 是有限的,如果它已经存在,它不会将项目插入到数组中,但它不会根据标识符更新项目。在这种情况下,我真的很想根据id 更新此条目。

db.soup.update({
     "tester": "tom"
 }, {
     $addToSet: {
         "array": {
             "id": "2",
             "letter": "c"
         }
     }
});

这给了我:

{
    "_id" : ObjectId("50b429ba0e27b508d854483e"),
    "array" : [
        {
            "id" : "1",
            "letter" : "a"
        },
        {
            "id" : "2",
            "letter" : "b"
        },
        {
            "id" : "2",
            "letter" : "c"
        }
    ],
    "tester" : "tom"
}

我真正想要的是:

{
    "_id" : ObjectId("50b429ba0e27b508d854483e"),
    "array" : [
        {
            "id" : "1",
            "letter" : "a"
        },
        {
            "id" : "2",
            "letter" : "c"
        }
    ],
    "tester" : "tom"
}

【问题讨论】:

    标签: node.js mongodb


    【解决方案1】:

    您可以使用$ 位置运算符来执行此操作:

    db.soup.update(
        {_id: ObjectId("50b429ba0e27b508d854483e"), 'array.id': '2'}, 
        {$set: {'array.$.letter': 'c'}})
    

    更新对象中的$ 充当array 的第一个元素的占位符,以匹配查询选择器。

    【讨论】:

    • 这很棒。我才意识到这就是我所拥有的。现在更复杂的问题是,我如何让它以一种 upsert 的方式将一个新对象(例如 {"id":3,"letter":"d"})推入数组?我是否必须以编程方式对请求进行排序?如果存在则使用$set 如果不存在则使用$push?
    • @ThomasReggi 如果您将其作为一个单独的问题提出会更好。
    【解决方案2】:

    给你:

    > db.collection.insert( { array : [ { id : 1, letter : 'a' }, { id : 2, letter : 'b' } ], tester : 'tom' } );
    > db.collection.findOne();
    {
        "_id" : ObjectId("50b431a69a0358d590a2f5f0"),
        "array" : [
            {
                "id" : 1,
                "letter" : "a"
            },
            {
                "id" : 2,
                "letter" : "b"
            }
        ],
        "tester" : "tom"
    }
    > db.collection.update( { tester : 'tom' }, { $set : { 'array.1' : { id : 2, letter : 'c' } } }, false, true );
    > db.collection.findOne();
    {
        "_id" : ObjectId("50b431a69a0358d590a2f5f0"),
        "array" : [
            {
                "id" : 1,
                "letter" : "a"
            },
            {
                "id" : 2,
                "letter" : "c"
            }
        ],
        "tester" : "tom"
    }
    

    诀窍在于假,真,假。 即:true 表示 upsert,false 表示更新倍数。

    更多详情请查看: http://www.mongodb.org/display/DOCS/Updating#Updating-update%28%29

    【讨论】:

    • 您正在根据数组位置 (array.1) 进行更新,而不是查找 id2 的条目。这仅在您已经知道数组中元素的位置时才有效,而不仅仅是id
    • 问题暗示标准是 { tester : 'tom' } 并且他想替换 'array' 列表的第二个元素。如果条件还必须包含 { 'array.id' : 2 },那么 JohnnyHK 的解决方案看起来就是这里的赢家。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-01
    • 2020-08-01
    • 2022-01-12
    • 2018-06-05
    • 2020-12-30
    相关资源
    最近更新 更多