JoeTidee
JoeTidee

Reputation: 26034

MongoDB - how do I update a value in nested array/object?

I have a document in my Mongo collection which has a field with the following structure:

"_id" : "F7WNvjwnFZZ7HoKSF",
"process" : [
    {
        "process_id" : "wTGqVk5By32mpXadZ", 
        "stages" : [
            {
                "stage_id" : "D6Huk89DGFsd29ds7",
                "completed" : "N"
            }, 
            {
                "stage_id" : "Msd390vekn09nvL23",
                "completed" : "N"
            }
        ]
    }
]

I need to update the value of completed where the stage_id is equal to 'D6Huk89DGFsd29ds7' - the update query will not know which object in the stages array this value of stage_id will be in.

How do I do this?

Upvotes: 1

Views: 58

Answers (2)

JoeTidee
JoeTidee

Reputation: 26034

In the end, I removed the outer process block, so that the process_id and stages were in the root of the document - made the process of updating easier using:

MyColl.update(
    {
        _id: 'F7WNvjwnFZZ7HoKSF',
        "stages.stage_id": 'D6Huk89DGFsd29ds7'
    },
    {
        $set: {"stages.$.completed": 'Y'}
    }
);

Upvotes: 0

Saleem
Saleem

Reputation: 8978

Since you have nested arrays in your object, this is bit tricky and I'm not sure if this problem can be solved with help of just one update query.

However, if you happen to know index of your matching object in first array, in your case process[0] you can write your update query like.

db.collection.update(
    {"process.stages.stage_id":"D6Huk89DGFsd29ds7"},
    {$set:{"process.0.stages.$.completed":"Y"}}
);

Query above will work perfect with your test case. Again, there is still possibility of having multiple objects at root level and there is no guarantee that matching object will always be at 0 index.

Solution I proposed above will fail if you have multiple children of process and if matching index of object is not zero.

However, you can achieve your goal with help of client side programming. That is find matching document, modify on client side and replace whole document with new content.

Since this approach is very in efficient, I'll suggest that you should consider altering your document structure to avoid nesting. Create another collection and move content of process array there.

Upvotes: 1

Related Questions