Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB, add new { field : value } in existing embedded document with multiple level dot notation?

Tags:

mongodb

What I am trying to do is add a new {field:value} for a blog post. So for example, if I wanted to start tracking impressions on websites.blog_posts.url: 'http://www.example.com/01.html' how can I add that impressions attribute for that blog post?

My current document structure:

{ 
email_address: '[email protected]', 
password: 'random_password',
first_name: 'John',
last_name: 'Doe',
user_type: 'WEBMASTER',
newsletter: 'NO',
websites: [{
    main_title: 'My Blog Website',
    main_url: 'http://www.example.com',
        blog_posts: [{
            url: 'http://www.example.com/01.html',
            title:'My first blog post',
            description: 'My first description.'
        }, { 
            url: 'http://www.example.com/02.html',
            title: 'My second blog post',
            description: 'My second description.'
        }, { 
            url: 'http://www.example.com/03.html',
            title: 'My third blog post',
            description: 'My third description.'
        }, { 
            url: 'http://www.example.com/04.html',
            title: 'My fourth blog post',
            description: 'My fourth description.'
        }]
    }]
}

Here is what I thought would work using update and making upsert TRUE.

db.my_collection.update( {'websites.blog_posts.url': 'http://www.example.com/01.html' }, {'$set': {'websites.blog_posts.impressions': 549}}, true )

The error that I received is: *can't append to array using string field name [blog_posts]*

Maybe "$set" is not correct for this or maybe I can not reference that deep with dot notation? I just started using MongoDB yesterday, any help would be great.

Thank you!

like image 664
Chris Avatar asked Oct 27 '11 13:10

Chris


People also ask

How do I add a field to an existing document in MongoDB?

To add field or fields to embedded documents (including documents in arrays) use the dot notation. See example. To add an element to an existing array field with $addFields , use with $concatArrays .

How do I update an embedded file in MongoDB?

Update Documents in an ArrayThe positional $ operator facilitates updates to arrays that contain embedded documents. Use the positional $ operator to access the fields in the embedded documents with the dot notation on the $ operator.

How do I add a field array to an existing document in MongoDB?

So, Adding a new field to an array is possible by using the update operation. $push operator is used to insert the field inside the array and if we want to add multiple fields, use $each inside $push.

Is it possible to update MongoDB field using value of another field?

Starting from MongoDB 4.2 you can perform Updates with an Aggregation Pipeline. An aggregation pipeline enables more expressive updates including calculated fields and references to other field values in the same document.


1 Answers

What you're trying to do is not possible given your schema. Dot-notation can be multi level but if there's more than one level that is an array it can no longer be addressed using the positional operator '$'.

E.g. you'd need to do :

db.my_collection.update( 
    {'websites.blog_posts.url': 'http://www.example.com/01.html' },
    {'$set': {'websites.$.blog_posts.$.impressions': 549}},
     true );

But having two position operators in the update is not possible since MongoDB can only determine the position of an element in the first array.

Your only option is to redesign your schema to have a dedicated collection of user websites (which is better for other reasons too in this case).

like image 95
Remon van Vliet Avatar answered Sep 17 '22 20:09

Remon van Vliet