Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Updating a specific key/value inside of an array field with MongoDB

Tags:

mongodb

As a preface, I've been working with MongoDB for about a week now, so this may turn out to be a pretty simple answer.

I have data already stored in my collection, we will call this collection content, as it contains articles, news, etc. Each of these articles contains another array called author which has all of the author's information (Address, Phone, Title, etc).

The Goal - I am trying to create a query that will update the author's address on every article that the specific author exists in, and only the specified author block (not others that exist within the array).

Sort of a "Global Update" to a specific article that affects his/her information on every piece of content that exists.

Here is an example of what the content with the author looks like.

{ 
"_id" : ObjectId("4c1a5a948ead0e4d09010000"), 
"authors" : [
    {
        "user_id" : null,
        "slug" : "joe-somebody",
        "display_name" : "Joe Somebody",
        "display_title" : "Contributing Writer",
        "display_company_name" : null,
        "email" : null,
        "phone" : null,
        "fax" : null,
        "address" : null,
        "address2" : null,
        "city" : null,
        "state" : null,
        "zip" : null,
        "country" : null,
        "image" : null,
        "url" : null,
        "blurb" : null
    },
    {
        "user_id" : null,
        "slug" : "jane-somebody",
        "display_name" : "Jane Somebody",
        "display_title" : "Editor",
        "display_company_name" : null,
        "email" : null,
        "phone" : null,
        "fax" : null,
        "address" : null,
        "address2" : null,
        "city" : null,
        "state" : null,
        "zip" : null,
        "country" : null,
        "image" : null,
        "url" : null,
        "blurb" : null
    },
], 
"tags" : [ 
    "tag1", 
    "tag2", 
    "tag3" 
], 
"title" : "Title of the Article" 
}

I can find every article that this author has created by running the following command:

db.content.find({authors: {$elemMatch: {slug: 'joe-somebody'}}});

So theoretically I should be able to update the authors record for the slug joe-somebody but not jane-somebody (the 2nd author), I am just unsure exactly how you reach in and update every record for that author.

I thought I was on the right track, and here's what I've tried.

b.content.update(
   {authors: 
     {$elemMatch: 
       {slug: 'joe-somebody'}
     }
   },
   {$set: 
     {address: '1234 Avenue Rd.'}
   },
   false,
   true
);

I just believe there's something I am missing in the $set statement to specify the correct author and point inside of the correct array. Any ideas?

**Update**

I've also tried this now:

b.content.update(
   {authors: 
     {$elemMatch: 
       {slug: 'joe-somebody'}
     }
   },
   {$set: 
     {'authors.$.address': '1234 Avenue Rd.'}
   },
   false,
   true
);

Solution:

This is what finally worked for me!

db.content.update({'authors.slug':'joe-somebody'},{$set:{'authors.$.address':'Address That I wanted'}},false,true);

It updates all the records properly, thanks!

like image 335
Jesta Avatar asked Jun 17 '10 18:06

Jesta


1 Answers

Maybe you can use the $ operator (positional-operator)?

like image 137
diederikh Avatar answered Sep 18 '22 12:09

diederikh