4

Possible Duplicate:
MongoDB updating fields in nested array

I have data like:

{ 
    "_id" : ObjectId("4f855061dd53351011000b42"), 
    "act_mgr" : [{ "sales" : {"agent" : ["[email protected]" ],  "last_interacted" : "[email protected]" } } ],
    "email" : "[email protected]", "name" : "Aman",
    "sales" : [{"sno" : 1,  "message" : "description","status" : "open"},{"sno" : 12,"message" : "assad","status" :"open"}]
}

I want to add new agent and update last_interacted in act_mgr:sales something like that

"act_mgr" : [{ "sales" : {"agent" : ["[email protected]","[email protected]" ],
 "last_interacted" : "[email protected]" } } ]

Also if I add new act_mgr like developer then it would be like

 "act_mgr" : [{ "sales" : {"agent" : ["[email protected]","[email protected]" ],  "last_interacted" : "[email protected]" } },
 { "developer" : {"agent" : ["[email protected]" ],  "last_interacted" : "[email protected]" } } ]

I dont know how to add these fields

2
  • Check this http://stackoverflow.com/questions/9611833/mongodb-updating-fields-in-nested-array/10412311#10412311 Commented May 2, 2012 at 11:00
  • 1
    Duplicate perhaps, but this question and answer are clearer than the earlier one. Commented Dec 17, 2014 at 15:19

1 Answer 1

6

You can update the embedded "sales" document inside of the "act_mgr" array with the following update statement:

> db.sales.update({"act_mgr.sales.last_interacted":"[email protected]"}, {$push:{"act_mgr.$.sales.agent":"[email protected]"}, $set:{"act_mgr.$.sales.last_interacted":"[email protected]"}})
> db.sales.find().pretty()
{
    "_id" : ObjectId("4f855061dd53351011000b42"),
    "act_mgr" : [
        {
            "sales" : {
                "agent" : [
                    "[email protected]",
                    "[email protected]"
                ],
                "last_interacted" : "[email protected]"
            }
        }
    ],
    "email" : "[email protected]",
    "name" : "Aman",
    "sales" : [
        {
            "sno" : 1,
            "message" : "description",
            "status" : "open"
        },
        {
            "sno" : 12,
            "message" : "assad",
            "status" : "open"
        }
    ]
}
> 

You can add the embedded document containing the "developer" information to the array like so:

> db.sales.update({"_id" : ObjectId("4f855061dd53351011000b42")}, {$push:{"act_mgr":{ "developer" : {"agent" : ["[email protected]" ],  "last_interacted" : "[email protected]" } }}})
> db.sales.find().pretty()
{
    "_id" : ObjectId("4f855061dd53351011000b42"),
    "act_mgr" : [
        {
            "sales" : {
                "agent" : [
                    "[email protected]",
                    "[email protected]"
                ],
                "last_interacted" : "[email protected]"
            }
        },
        {
            "developer" : {
                "agent" : [
                    "[email protected]"
                ],
                "last_interacted" : "[email protected]"
            }
        }
    ],
    "email" : "[email protected]",
    "name" : "Aman",
    "sales" : [
        {
            "sno" : 1,
            "message" : "description",
            "status" : "open"
        },
        {
            "sno" : 12,
            "message" : "assad",
            "status" : "open"
        }
    ]
}
> 

The documentation on the $push and $set modifiers may be found in the "Updating" documentation: http://www.mongodb.org/display/DOCS/Updating

More information on creating and updating embedded documents with Mongo db may be found in the documentation titled "Dot Notation (Reaching into Objects)" http://www.mongodb.org/display/DOCS/Dot+Notation+%28Reaching+into+Objects%29

Information on updating embedded documents using the "$" positional operator may be found in the "The $ positional operator" section of the "Updating" documentation.
http://www.mongodb.org/display/DOCS/Updating#Updating-The%24positionaloperator

A word of caution: It is generally more common to have embedded documents all match the same structure, so that individual embedded documents may be referenced more easily. Your "sales" array is a good example of this; each embedded document contains the same keys, "sno", "message", and"status"

However, the embedded documents inside your "act_mgr" array contain different keys; the first contains "sales", and the second contains "developer". Instead, maybe consider the following structure:

"act_mgr" : [
    {
        "title" : "sales",
        "agent" : [
            "[email protected]",
            "[email protected]"
        ],
        "last_interacted" : "[email protected]"
    },
    {
        "title": "developer",
        "agent" : [
            "[email protected]"
        ],
        "last_interacted" : "[email protected]"
    }
]

Now, each embedded documents contain the same keys, "title", "agent", and "last_interacted".

You could update sub-documents with the following command.

> db.sales.update({"act_mgr.title":"sales"}, {$push:{"act_mgr.$.agent":"[email protected]"}, $set:{"act_mgr.$.last_interacted":"[email protected]"}})

Hopefully this will allow you to make the updates that you need to, and perhaps give you some food for thought regarding schema design. Good luck!

Sign up to request clarification or add additional context in comments.

2 Comments

But I have to update this record by _id like db.sales.update({"_id" : ObjectId("4f855061dd53351011000b42")},{...})
In my example I just used _id because it was convenient. Your query document may match any value. Notice that the first example uses "act_mgr.sales.last_interacted" in the query document. This is explained in the "Updating" documentation referenced above.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.