MongoDB:更新数组中的数组

时间:2015-06-11 14:37:04

标签: arrays mongodb object schema

我似乎在访问嵌套在mongodb文档中的数组中的数组内容时遇到问题。通过以下查询访问第一个数组“groups”没有问题...

db.orgs.update({_id: org_id, "groups._id": group_id} , {$set: {"groups.$.name": "new_name"}});

当我遇到麻烦时,我试图修改嵌套在“group”数组中的数组“features”中元素的属性。

以下是示例文档的内容

     {
        "_id" : "v5y8nggzpja5Pa7YS",
        "name" : "Example",
        "display_name" : "EX1",
        "groups" : [
            {
                "_id" : "s86CbNBdqJnQ5NWaB",
                "name" : "Group1",
                "display_name" : "G1",
                "features" : [
                    {
                        _id      : "bNQ5Bs8BWqJn6CdNa"
                        type     : "blog",
                        name     : "[blog name]"
                        owner_id : "ga5YgvP5yza7pj8nS"
                    }, 
                ]
             },
         ]
     },

这是我试图使用的查询。

db.orgs.update({_id: "v5y8nggzpja5Pa7YS", "groups._id": "qBX3KDrtMeJGvZWXZ", "groups.features._id":"bNQ5Bs8BWqJn6CdNa" }, {$set: {"groups.$.features.$.name":"New Blog Name"}});

返回错误消息:

WriteResult({
    "nMatched" : 0,
    "nUpserted" : 0,
    "nModified" : 0,
    "writeError" : {
        "code" : 2,
        "errmsg" : "Too many positional (i.e. '$') elements found in path 'groups.$.features.$.name'"
    }
})

似乎mongo不支持通过位置元素修改嵌套在数组中的数组?

有没有办法修改这个数组而不把整个事情拿出来,修改它,然后把它放回去?像这样的多个嵌套是创建新集合的标准做法吗? (即使只在需要父数据时才需要数据)我应该更改文档结构,以便第二个嵌套数组是一个对象,并通过密钥访问它? (其中键是一个整数值,可以作为“_id”)

groups.$.features.[KEY].name

什么被认为是“正确”的方法?

1 个答案:

答案 0 :(得分:3)

经过一些研究后,看起来修改数组中数组的唯一方法是使用一些外部逻辑来查找我想要更改的元素的索引。这样做需要每次更改都有一个查找查询来查找索引,然后是一个更新查询来修改数组。这似乎不是最好的方法。

Link to a 2010 JIRA case requesting multiple positional elements...

由于我将始终知道该功能的ID,因此我选择修改我的文档结构。

     {
    "_id" : "v5y8nggzpja5Pa7YS",
    "name" : "Example",
    "display_name" : "EX1",
    "groups" : [
        {
            "_id" : "s86CbNBdqJnQ5NWaB",
            "name" : "Group1",
            "display_name" : "G1",
            "features" : {
               "1" : {
                       type     : "blog",
                       name     : "[blog name]"
                       owner_id : "ga5YgvP5yza7pj8nS"
               }, 
            }
         },
     ]
 },

使用新结构,可以通过以下方式进行更改:

db.orgs.update({_id: "v5y8nggzpja5Pa7YS", "groups._id": "s86CbNBdqJnQ5NWaB"}, {$set: {"groups.$.features.1.name":"Blog Test 1"}});