MongoDB:更新数组中的数组

Jam*_*mes 6 arrays schema object mongodb

我似乎在访问嵌套在mongodb文档中的数组中的数组的内容时遇到问题.使用如下查询访问第一个数组"groups"没有问题...

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

我遇到麻烦的地方是当我尝试修改嵌套在"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"
                    }, 
                ]
             },
         ]
     },
Run Code Online (Sandbox Code Playgroud)

这是我试图使用的查询.

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

它返回一条错误消息:

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

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

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

groups.$.features.[KEY].name
Run Code Online (Sandbox Code Playgroud)

什么被认为是"正确"的方式?

Jam*_*mes 3

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

链接到 2010 年 JIRA 案例,请求多个位置元素...

由于我始终知道该功能的 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"
               }, 
            }
         },
     ]
 },
Run Code Online (Sandbox Code Playgroud)

对于新的结构,可以通过以下方式进行更改:

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