Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB Update Deep Array

Tags:

mongodb

I have the following object in my mongo database named music.

I want to update where the genre is Grunge
The band name is Nirvana
The album name is Nevermind
The track order is 1

and change the track's name to "Smells Like Teen Spirit!".
I've tried playing with the positional operator, but can't quite figure this out.

{
    genre : "Grunge",
    bands : [ {
        name : "Nirvana",
        albums : [ {
            name : "Nevermind",
            tracks : [ {
                name : "Smell Like Teen Spirit",
                order : 1,
                duration : 301
            },
            {
                name : "In Bloom",
                order : 2,
                duration : 254                                                  
            } ]
        },
        {
            name : "In Utero",
            tracks : [ {
                name : "Server the Servants",
                order : 1,
                duration : 216
            },
            {
                name : "Scentless Apprentice",
                order : 2,
                duration : 254                                                  
            } ]
        } ]
    },
    {
        name : "Karma++ : A Nirvina Tribute Band",
        albums : [ {
            name : "Nevermind",
            tracks : [ {
                name : "Smell Like Teen Spirit",
                order : 1,
                duration : 301
            },
            {
                name : "In Bloom",
                order : 2,
                duration : 254                                                  
            } ]
        },
        {
            name : "In Utero",
            tracks : [ {
                name : "Server the Servants",
                order : 1,
                duration : 216
            },
            {
                name : "Scentless Apprentice",
                order : 2,
                duration : 254                                                  
            } ]
        } ]
    } ]
}
like image 439
JWally Avatar asked Apr 26 '12 20:04

JWally


People also ask

How do I update an entire array in MongoDB?

You can use the updateOne() or updateMany() methods to add, update, or remove array elements based on the specified criteria. It is recommended to use the updateMany() method to update multiple arrays in a collection.

How do I update a nested array in MongoDB?

Update Nested Arrays in Conjunction with $[]The $[<identifier>] filtered positional operator, in conjunction with the $[] all positional operator, can be used to update nested arrays. The following updates the values that are greater than or equal to 8 in the nested grades. questions array if the associated grades.


1 Answers

Unfortunately, at present it is only possible to use a single "$" positional per update. This limits the update to a single embedded array, similar to the example in the documentation: http://www.mongodb.org/display/DOCS/Updating#Updating-The%24positionaloperator (From your post, it looks like you have already found this, but I have included the link for the benefit of any other users reading this post.)

In order to make the update, you will have to know the position of two out of the following three: The position of the band in the "bands" array, the position of the album in the albums array, or the position of the track in the "tracks" array.

There is a feature request for this functionality, and it is slated for version 2.3.0 (although this is subject to change).
https://jira.mongodb.org/browse/SERVER-831 "Positional Operator Matching Nested Arrays"

For the time being, you will have to know the position of the sub documents in two out of the three arrays:

db.music.update({genre : "Grunge", "bands.name" : "Nirvana"}, {$set:{"bands.$.albums.0.tracks.0.name":"Smells Like Teen Spirit!"}})

db.music.update({genre : "Grunge", "bands.0.albums.name" : "Nevermind"}, {$set:{"bands.0.albums.$.tracks.0.name":"Smells Like Teen Spirit!"}})

or

db.music.update({genre : "Grunge", "bands.0.albums.0.tracks.order" : 1}, {$set:{"bands.0.albums.0.tracks.$.name":"Smells Like Teen Spirit!"}})
like image 146
Marc Avatar answered Oct 23 '22 18:10

Marc