6

我试图从三重嵌套数组中删除一个属性,但没有成功。这是我要删除的数据的示例:

Controls: [
    {    
        Name: 'ControlNumberOne',
        Submit: {   
            Executes: [
                {
                    Name: 'execute',
                    Type: 0
                },
                {
                    Name: 'anotherExecute',
                    Type: 0
                }
            ]
        }
    },
    {    
        Name: 'ControlNumberTwo',
        Submit: {   
            Executes: [
                {
                    Name: 'anotherFromAnotherControl',
                    Type: 1
                }
            ]
        }
    }

]

我尝试了以下更新查询,但没有一个有效:

  • db.Page.update('Controls.Submit.Executes.Type': { $exists : true } }, { $unset : { 'Controls.Submit.Executes.Type' : 1 } }, false, true);)

  • db.Page.update('Controls.Submit.Executes.Type': { $exists : true } }, { $unset : { 'Controls.$.Submit.Executes.$.Type' : 1 } }, false, true);)

但是,如果我执行db.Page.find('Controls.Submit.Executes.Type': { $exists : true } })它确实会返回所有仍然具有 Type 属性的 Executes。

这可以实现吗?谢谢!

4

2 回答 2

5

MongoDB 命令不(还)直接支持查询和更新嵌套数组,这必须在客户端完成:

  • 将文档读入变量
  • 操作数组
  • 更新文档,重写整个数组

在 Jira 上查看此问题:https ://jira.mongodb.org/browse/SERVER-831和 stackoverflow 上的此线程:Mongo update of subdocs

鉴于您的示例,这将如下所示:

db.xx.find(
    {'Controls.Submit.Executes.Type': { $exists : true } }
).forEach( function(doc) {
    doc.Controls.forEach( function(c) {
        c.Submit.Executes.forEach( function(e) {
            if ( e.Type != undefined ) delete e.Type;        
        });
    });
    db.xx.update({_id: doc._id},{$set:{Controls:doc.Controls}});
});

结果是:

> db.xx.findOne()
{
    "Controls" : [
        {
            "Name" : "ControlNumberOne",
            "Submit" : {
                "Executes" : [
                    {
                        "Name" : "execute"
                    },
                    {
                        "Name" : "anotherExecute"
                    }
                ]
            }
        },
        {
            "Name" : "ControlNumberTwo",
            "Submit" : {
                "Executes" : [
                    {
                        "Name" : "anotherFromAnotherControl"
                    }
                ]
            }
        }
    ],
    "_id" : ObjectId("5159ff312ee0f7d445b03f32")
}
于 2013-04-01T22:10:38.113 回答
5

如果有人仍在寻找答案(像我一样),就在这里。

在 MongoDB 版本 3.6+ 中,现在可以使用位置运算符更新数组中的所有项目,包括更深的嵌套级别。请参阅此处的官方文档。:

db.getCollection('xxx').update(
   {'Controls.Submit.Executes.Type': { $exists : true },
   { $unset : {'Controls.$[].Submit.Executes.$[].Type' : 1}}
)

此代码经过测试,可与 MongoDB CLI、RoboMongo 和 Mongo-Java 驱动程序很好地配合使用。

于 2019-07-08T07:29:01.923 回答