6

I'm trying to remove an attribute from a triple-nested array without success. Here is an example of the data I want to remove:

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

]

I tried the following update queries but none of them worked:

  • 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);)

However, if I execute db.Page.find('Controls.Submit.Executes.Type': { $exists : true } }) it does return all the Executes that still have a Type attribute.

Can this be achieved? Thanks!

2
  • Your Executes seems to be an object, not an array. Commented Mar 7, 2013 at 20:17
  • you're right I mispelled it... please take a look at it now! Commented Mar 8, 2013 at 0:47

2 Answers 2

9

If anyone is still looking for an answer (like me), here it is.

With MongoDB version 3.6+, it is now possible to use the positional operator to update all items in an array, including the deeper nested level. See official documentation here.:

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

This code is tested and works well with MongoDB CLI, RoboMongo and Mongo-Java driver.

Sign up to request clarification or add additional context in comments.

Comments

5

Querying and updating of nested arrays is not (yet) supported by MongoDB commands directly, this has to be done on the client side:

  • read the document into a variable
  • manipulate the array
  • update the document, rewriting the entire array

See this issue on Jira: https://jira.mongodb.org/browse/SERVER-831 and this thread on stackoverflow: Mongo update of subdocs

Given your example, this would look like this:

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

and the result is:

> db.xx.findOne()
{
    "Controls" : [
        {
            "Name" : "ControlNumberOne",
            "Submit" : {
                "Executes" : [
                    {
                        "Name" : "execute"
                    },
                    {
                        "Name" : "anotherExecute"
                    }
                ]
            }
        },
        {
            "Name" : "ControlNumberTwo",
            "Submit" : {
                "Executes" : [
                    {
                        "Name" : "anotherFromAnotherControl"
                    }
                ]
            }
        }
    ],
    "_id" : ObjectId("5159ff312ee0f7d445b03f32")
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.