MongoDB:更新数组中的数组

MongoDB: updating an array in array

我在访问嵌套在 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"}});

它 returns 带有错误消息:

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

执行此操作的 "correct" 方法是什么?

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

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"}});