1

I have a document :

{
        "_id" : ObjectId("550c00f81bcc15211016699b"),
        "name" : "book3",
        "author" : "mno",
        "publisher" : "pub",
        "testa" : [
                {
                        "item1" : "item1",
                        "item2" : "item2"
                }
        ]
}

All I want to do is add another item in testa like:

{
        "_id" : ObjectId("550c00f81bcc15211016699b"),
        "name" : "book3",
        "author" : "mno",
        "publisher" : "pub",
        "testa" : [
                {
                        "item1" : "item1",
                        "item2" : "item2",
                        "item3  : "item3"
                }
        ]
}

I tried using

db.books.update(
   { "author":"mno" },
   { $addToSet: { testa : {"item3":"item3"} } }
)

this gives

{
        "_id" : ObjectId("550c05261bcc15211016699c"),
        "name" : "book3",
        "author" : "mno",
        "publisher" : "pub",
        "testa" : [
                {
                        "item1" : "item1",
                        "item2" : "item2"
                },
                {
                        "item3" : "item3"
                }
        ]
}

and i tried

db.books.update(
   { "author":"mno" , "testa.item1" : "item1"},
   { $set : {"testa.0" : {"item3":"item3"}}},
   {upsert : true / false}
   )

this gave

{
        "_id" : ObjectId("550c05fa1bcc15211016699d"),
        "name" : "book3",
        "author" : "mno",
        "publisher" : "pub",
        "testa" : [
                {
                        "item3" : "item3"
                }
        ]
}

Am I doing something wrong, I checked everywhere Insert an embedded document to a new field in mongodb document and Update or replace an embedded document in MongoDB collection

I tried wierd things... but.... Please help me get the query right

I also tried these using the C# driver like

WriteConcernResult res = booksColl.Update(query, Update.Set("testa.$.item1", "itemedited"),UpdateFlags.Upsert);
Saud Khan
  • 123
  • 4
  • 1
    With this schema it's going to be a bit hard to do write operations on documents where the array object has dynamic keys. If you are flexible enough I would recommend you change the schema to have the `testa` array hold elements with the following structure e.g. `[{"name": "item1", "value": "item1"}, {"name": "item2", "value": "item2"}]` which you can then update by `db.books.update( { "author":"mno" }, { $addToSet: { "testa": {"name": "item3", "value": "item3"}} } )` – chridam Mar 20 '15 at 12:02
  • Thanks . I was actually thinking the same thing, but I need to re-design the whole schema, so... Is there no way this can be done other than deleting the whole array and re-inserting it – Saud Khan Mar 20 '15 at 12:19

2 Answers2

1

The following statement should work

db.books.update(
   { "author":"mno" },
   { $set: { "testa.0.item3" : "item3"} } 
)

You can use the dot notation to specify items in the array and then you can just set the new item3 field to what ever value you wish. You nearly had it right in your examples above - you just need to specify "testa.0.item3" instead of "testa.0"

I would agree with @chridam's comment above though and changing the schema would make the document easier to work with going forward. It might be some extra work now but it will save you in the long run.

Kevin Brady
  • 1,684
  • 17
  • 30
  • But this did add an item to the testa array like testa:[{"item1":"item1","item2":"item2"},{item3:item3}] – Saud Khan Mar 22 '15 at 16:44
  • I've run it in my local mongo shell and it has worked correctly. The testa.0.item3 value of the $set command is targeting the item3 property of the 0 placed document in the testa array of documents. Using a value of testa.1.item3 on the $set command would give you the result you mentioned above – Kevin Brady Mar 23 '15 at 12:17
0

Actually you don't have a collection of items, you have a collections of documents which have items as keys:values, if this is the goal, the update may be:

> db.books.update({ "author":"mno" },{$set: {"testa.0.item3":"item3"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

> db.books.find().pretty()
{
        "_id" : ObjectId("550c00f81bcc15211016699b"),
        "name" : "book3",
        "author" : "mno",
        "publisher" : "pub",
        "testa" : [
                {
                        "item1" : "item1",
                        "item2" : "item2",
                        "item3" : "item3"
                }
        ]
}
user55993
  • 311
  • 3
  • 6