markdsievers
markdsievers

Reputation: 7309

add property to nested array in mongodb document

I have a mongodb document with the following structure

> db.user.find().limit(1);
{ "_id" : "1", "foo" : { "bars" : [
    {
        "name" : "bar1"
    },
    {
        "name" : "bar2"
    },
], ... }, ... }

I want to add a new property to each bar. I've got my script iterating over the bars array, but I can't get the new property in there, how can I do this?

var users = db.user.find({"foo.bars":{$exists:true}});

users.forEach(function(user) {
    user.foo.bars.forEach(function(bar)
    {
       printjson(bar);
       //how can I specify the current 'bar' in this update?
       //db.experience.update({_id: user._id}, {$set: {"what goes here?" : "newbarValue"}});
    });
});

Upvotes: 6

Views: 6006

Answers (3)

stuartrexking
stuartrexking

Reputation: 657

So says the preacher man:

var users = db.user.find({"foo.bars":{$exists:true}});

users.forEach(function(user) {
    var id = user._id;

    var foo_bars = user.foo.bars;
    var new_foo_bars = [];

    for(var i = 0; i < foo_bars.length; i++) {
        var foo_bar = foo_bars[i];
        foo_bar['newkey'] = 'newvalue';
        new_foo_bars.push(foo_bar);
    }

    db.user.update({"_id":id}, {$set:{"foo.bars":new_foo_bars}});
});

Upvotes: 10

Sammaye
Sammaye

Reputation: 43884

I have noticed that you are scrolling through the array on the client side there in JS.

If you were to form a new "bars" array from the old one then push it in as a whole new value this would mean you only do one DB call and the code is quite elegant.

If MongoDB does not support it normally it is better to just do the work on the client side.

Upvotes: 1

user2665694
user2665694

Reputation:

You have to update each element of the nested document individually. Using the positional operator '$' will not work since it will only work on the first match (as documented).

Upvotes: 0

Related Questions