2

I've just started working with MongoDB. And I have a document like this:

   {

     "_id": "12345" 
     "body": "Here is the body" 
     "comments":[
                {
                  "name": "Person 1"
                  "comm": "My comment"},
                {
                  "name": "Person 2"
                  "comm": "Comment 2"}
             ] 
    "author":"Author 1" 
}

And I want to change this document to :

   {

    "_id": "12345" 
     "body": "Here is the body" 
     "comments":[
                {
                  "name": "Person 1"
                  "comm": "My comment"
                  "checks_": 1
                 },
                {
                  "name": "Person 2"
                  "comm": "Comment 2"
                  "checks_": 4
                }
             ] 
    "author": "Author 1" 
}

I've tried:

db.coll.update({ "_id":12345},{ "$set":{ "comments" :{ "checks_": 1}}})

And this removed all sub documents within comments and added {checks_:1} to it.

Where am I going wrong?

Neil Lunn
  • 148,042
  • 36
  • 346
  • 317
Saturnian
  • 1,686
  • 6
  • 39
  • 65
  • possible duplicate of [how to update multiple array elements in mongodb](http://stackoverflow.com/questions/4669178/how-to-update-multiple-array-elements-in-mongodb) – joao Mar 23 '14 at 07:53
  • Couldn't find the solution that'd help me.. – Saturnian Mar 23 '14 at 07:59
  • 1
    If you want to update a single array subdocument you can do db.coll.update({_id:12345},{$set:{"comments.0.checks_":1}}). This will update the document at array index 0. – joao Mar 23 '14 at 08:09
  • What if i need to do in all sub array in one go? – Dhruv Kaushal Aug 05 '19 at 13:28

3 Answers3

7

So what you are doing wrong is that the $set operator is doing exactly what it should, and it is replacing only the comments field with the value you have specified. This is not adding an additional document to the array.

You need to be specific and use "dot notation" to "indentify" which array element you are replacing. So to get to your result, you need two updates:

db.coll.update({ "_id":12345},{ "$set":{ "comments.0.checks_" : 1 }})
db.coll.update({ "_id":12345},{ "$set":{ "comments.1.checks_" : 4 }})

That is at least until the next version (as of writing) of MongoDB is released, where you can do bulk updates. And that will not be long now.

Neil Lunn
  • 148,042
  • 36
  • 346
  • 317
1

A little more geneirc solution (for MongoDb 3.6+):

db.coll.update(
{},
{$set: {"comments.$[element].checks_": 1}},
{multi: false, arrayFilters: [{"element.name": {$eq: "Person 1"}}]}
)

This will add field into specific sub document from the list, matching criteria (name = 'Person 1').

Dimitar II
  • 2,299
  • 32
  • 33
0

Adding my two cents here. If you want to add a field to the all the cells, with the same value (in this example: 1 will be added to all of them). You can use the following command:

db.coll.updateMany( {"_id": 12345}, {"$set": {"comments.$[].checks_": 1} }});

And you will get

{

    "_id": "12345" 
     "body": "Here is the body" 
     "comments":[
                {
                  "name": "Person 1"
                  "comm": "My comment"
                  "checks_": 1
                 },
                {
                  "name": "Person 2"
                  "comm": "Comment 2"
                  "checks_": 1
                },
                ...
                {
                  "name": "Person 300"
                  "comm": "Comment 300"
                  "checks_": 1
                }
             ] 
    "author": "Author 1" 
}
Moyshe Zuchmir
  • 1,522
  • 12
  • 18