67

I want add new data my nested array

My document is:

{
  "username": "erkin",
  "email": "erkin-07@hotmail.com",
  "password": "b",
  "playlists": [
    {
      "_id": 58,
      "name": "asdsa",
      "date": "09-01-15",
      "musics": [
        {
          "name": "INNA - Cola Song (feat. J Balvin)",
          "duration": "3.00"
        },
        {
          "name": "blabla",
          "duration": "3.00"
        }
      ]
    }
  ]
}

I want add music in this playlist section:

{
  "username": "erkin",
  "email": "erkin-07@hotmail.com",
  "password": "b",
  "playlists": [
    {
      "_id": 58,
      "name": "asdsa",
      "date": "09-01-15",
      "musics": [
        {
          "name": "INNA - Cola Song (feat. J Balvin)",
          "duration": "3.00"
        },
        {
          "name": "blabla",
          "duration": "3.00"
        },
        {
          "name": "new",
          "duration": "3.00"
        }
      ]
    }
  ]
}

Here is what I tried:

$users->update(
  array(
    '_id' => new MongoId (Session::get('id')),
    'playlists._id' => $playlistId
  ),
  array(
    '$push' => array('playlists.musics' => array(
      'name' => 'newrecord',
      'duration' => '3.00'
    ))
  )
);
Mostafiz Rahman
  • 8,169
  • 7
  • 57
  • 74
balkondemiri
  • 933
  • 3
  • 11
  • 16
  • 5
    Just to fill you in on the reason people downvote or vote to close here. Post the relevant parts of code in your question. Do not externally link ( likely to break ) and don't make us read though long listings just to work out what you are talking about. Read this: http://stackoverflow.com/help/mcve – Neil Lunn Jan 10 '15 at 09:38

4 Answers4

110

Probably something like this where ID is your ObjectId. The first {} are necessary to identify your document. It is not required to use an ObjectId as long as you have another unique identifier in your collection.

db.collection.update(
    { "_id": ID, "playlists._id": "58"},
    { "$push": 
        {"playlists.$.musics": 
            {
                "name": "test name",
                "duration": "4.00"
            }
        }
    }
)
Neil Lunn
  • 148,042
  • 36
  • 346
  • 317
Thomas Bormans
  • 5,156
  • 6
  • 34
  • 51
  • Hi. You not specify playlist _id. I have multiple playlist every user – balkondemiri Jan 10 '15 at 11:41
  • 1
    @balkondemiri That possible. I am not able to test it so it was a guess. Nevertheless it should put you in the right direction. – Thomas Bormans Jan 10 '15 at 18:36
  • Mongodb console say "exception: SyntaxError: Unexpected token ." http://paste.ubuntu.com/9706780/ – balkondemiri Jan 10 '15 at 18:44
  • @balkondemiri The `"playlists._id"` key needs to be "quoted" much as I have done here. It was just a syntax mistake in the answer. It is good practice to "quote" all keys in object definitions. JavaScript allows you do "valid" things without the quotes, but true JSON expects quoted keys. – Neil Lunn Jan 11 '15 at 01:27
  • @NeilLunn I add "quoted" now. It's don't add new data. Console return { "retval": null, "ok": 1 } Why i am wrong ? – balkondemiri Jan 11 '15 at 05:58
  • @balkondemiri Works for everyone else in the world. `.update()` does not return the altered document `.findAndModify()` does that with options set. The code as listed here works fine. Are you actually checking the document in the collection? Or just assuming "not works" because you didn't get the document i the response? Make sure your document `_id` and `playlists._id` values match something valid. – Neil Lunn Jan 11 '15 at 06:04
  • 3
    Thank you everyone. I update my query. {"_id": ObjectId("54ad6c115e03635c0c000029"), "playlists._id": 58} – balkondemiri Jan 11 '15 at 06:19
  • I have gone through your solution and its working up to 2nd level of my multi level database. I'm trying to insert new node inside to the in-depth level of the database. Please refer here my question about it & help me back. Link: https://stackoverflow.com/questions/47429643/how-can-i-insert-a-new-entry-inside-multilevel-structure-of-mongodb-database – Purvik Rana Nov 22 '17 at 08:40
  • given that we have a limit for $push which i believe is 16 mb per document, is there way to create a new document when the $push fails or say keep only 1000 array elements per document? – PirateApp Feb 25 '18 at 05:23
  • I want to apply the same logic for all the documents my collection from python. what will be the syntax in python for the same problem ? Thanks. – Nidhi Arora Jul 31 '20 at 09:22
  • Thanks for saving my time – Harish Verma Jan 20 '21 at 18:40
  • I think ```arrayFilters``` is a better solution, i added this solution down below. – doruksahin May 03 '22 at 10:31
6

This way it worked for me!

"playlists.$[].musics":

db.collection.update(
{ "_id": ID, "playlists._id": "58"},
{ "$push": 
    {"playlists.$[].musics": 
        {
            "name": "test name",
            "duration": "4.00"
        }
    }
 }
)

https://docs.mongodb.com/manual/reference/operator/update/positional-filtered/#position-nested-arrays-filtered

adflytec
  • 117
  • 1
  • 7
5

I suggest you using arrayFilters since it supports multiple nested documents and clearer.

db.collection.update(
{ "_id": ID},
{ "$push": 
    {"playlists.$[i].musics": 
        {
            "name": "test name",
            "duration": "4.00"
        }
    }
 },
    {
        arrayFilters: [
          {'i._id': 58,},
        ],
      },
)
doruksahin
  • 332
  • 1
  • 5
  • 11
0

2022 update:

Full snippet:

from pymongo import MongoClient
client = MongoClient('mongodb://localhost:27017/', maxPoolSize=50)

db = client.name_of_db
collection = db["name_of_collection"]

To push:

collection.find_one_and_update(
    {"_id": 'id_of_the_document'}, 
    {"$push": {"key":"value"}})

To push into nested:

collection.find_one_and_update(
    {"_id": 'id_of_the_document'}, 
    {"$push": {"key.nested_key":"value"}})
Žygimantas
  • 302
  • 2
  • 13