Mongodb $push in nested array
Asked Answered
C

4

68

I want add new data my nested array

My document is:

{
  "username": "erkin",
  "email": "[email protected]",
  "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": "[email protected]",
  "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'
    ))
  )
);
Comus answered 10/1, 2015 at 8:55 Comment(1)
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: stackoverflow.com/help/mcveVaillancourt
G
111

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"
            }
        }
    }
)
Gloxinia answered 10/1, 2015 at 11:26 Comment(12)
Hi. You not specify playlist _id. I have multiple playlist every userComus
@Comus That possible. I am not able to test it so it was a guess. Nevertheless it should put you in the right direction.Gloxinia
Mongodb console say "exception: SyntaxError: Unexpected token ." paste.ubuntu.com/9706780Comus
@Comus 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.Vaillancourt
@NeilLunn I add "quoted" now. It's don't add new data. Console return { "retval": null, "ok": 1 } Why i am wrong ?Comus
@Comus 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.Vaillancourt
Thank you everyone. I update my query. {"_id": ObjectId("54ad6c115e03635c0c000029"), "playlists._id": 58}Comus
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: #47430143Engross
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?Filet
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.Howey
Thanks for saving my timeWhitechapel
I think arrayFilters is a better solution, i added this solution down below.Recife
A
8

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

Acuminate answered 24/10, 2018 at 2:55 Comment(1)
this will push the new record in all the array elements of "playlists" entity.Giacinta
R
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,},
        ],
      },
)
Recife answered 3/5, 2022 at 10:27 Comment(0)
S
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"}})
Salop answered 3/5, 2022 at 15:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.