MongoDb:如何从嵌套数组中取消设置属性?

时间:2013-03-07 18:27:58

标签: mongodb

我尝试从三重嵌套数组中删除属性但没有成功。以下是我要删除的数据示例:

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。

这可以实现吗?谢谢!

2 个答案:

答案 0 :(得分: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")
}

答案 1 :(得分:0)

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

在MongoDB 3.6+版中,现在可以使用位置运算符更新数组中的所有项目,包括更深的嵌套级别。参见official documentation here。:

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

此代码已经过测试,可与MongoDB CLI,RoboMongo和Mongo-Java驱动程序完美配合。