修改MongoDB中数组内的文档

时间:2014-03-26 11:15:48

标签: mongodb mongodb-query

过去的答案(从2013年中期及之前)似乎不起作用,文档链接都已过时。

示例用户对象:

{
    "name": "Joe Bloggs",
    "email": "joebloggs@example.com",
    "workstations" : [
                         { "number" : "10001",
                           "nickname" : "home" },
                         { "number" : "10002",
                           "nickname" : "work" },
                         { "number" : "10003",
                           "nickname" : "vacation" }
                     ]
}

如何修改工作站的昵称?

我尝试使用$setworkstations.$workstations.nickname,但都没有达到预期效果。

3 个答案:

答案 0 :(得分:1)

简短的回答,你必须使用数组索引。例如,您要更新昵称10002{$set:{"workstations.1.nickname":"newnickname"}}

以下是完整的示例:

> db.test.update({"_id" : ObjectId("5332b7cf4761549fb7e1e72f")},{$set:{"workstations.1.nickname":"newnickname"}})
> db.test.findOne()
{
        "_id" : ObjectId("5332b7cf4761549fb7e1e72f"),
        "email" : "joebloggs@example.com",
        "name" : "Joe Bloggs",
        "workstations" : [
                {
                        "number" : "10001",
                        "nickname" : "home"
                },
                {
                        "nickname" : "newnickname",
                        "number" : "10002"
                },
                {
                        "number" : "10003",
                        "nickname" : "vacation"
                }
        ]
}
>

如果您不知道索引(工作站的位置),则可以使用$elemMatch更新文档:

>db.test.update(
    { 
        "email": "joebloggs@example.com",
        "workstations": { "$elemMatch" { "number" : "10002" } }
    },
    {
        "$set": { "workstations.$.nickname": "newnickname2" }
    }
)
>

答案 1 :(得分:1)

@ naimdjon的答案会起作用。要概括起来,您可以将$elemMatch运算符与$ positional运算符结合使用以下查询来更新数组中的一个元素

db.test.update({
    // Find the document where name="Joe Bloggs" and the element in the workstations array where number = "10002"
    "name": "Joe Bloggs", 
    "workstations":{$elemMatch:{"number":"10002"}}
},
{
    // Update the nickname in the element matched 
    $set:{"workstations.$.nickname":"newnickname"}
})

注意: $ elemMatch仅在您需要匹配阵列中的多个组件时才需要。如果您要仅使用number进行匹配,则可以使用"workstations.number":"10002"

答案 2 :(得分:1)

只要你知道"哪个"您希望更新的条目,然后positional $运营商可以提供帮助。但是您需要更新您的查询表单:

db.collection.update(
    { 
        "email": "joebloggs@example.com",
        "workstations": { "$elemMatch" { "nickname" : "work" } }
    },
    {
        "$set": { "workstations.$.nickname": "new name" }
    }
)

这是一般形式。您需要在这里做的是"匹配"数组中的某些东西,以获得一个"位置"用于更新。

或者,如果您知道这个职位,那么您只需指定"带有"点符号的位置":

db.collection.update(
    { 
        "email": "joebloggs@example.com",
    },
    {
        "$set": { "workstations.1.nickname": "new name" }
    }
)

更新数组中的 second 元素,并且不需要"匹配"参与查询。