4

Possible Duplicate:
MongoDB updating fields in nested array

I have data like:

{ 
    "_id" : ObjectId("4f855061dd53351011000b42"), 
    "act_mgr" : [{ "sales" : {"agent" : ["rohan@walkover.in" ],  "last_interacted" : "rohan@walkover.in" } } ],
    "email" : "aman@asasas.com", "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" : ["rohan@walkover.in","abc@walkover.in" ],
 "last_interacted" : "abc@walkover.in" } } ]

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

 "act_mgr" : [{ "sales" : {"agent" : ["rohan@walkover.in","abc@walkover.in" ],  "last_interacted" : "abc@walkover.in" } },
 { "developer" : {"agent" : ["newdeveloper@walkover.in" ],  "last_interacted" : "newdeveloper@walkover.in" } } ]

I dont know how to add these fields

Community
  • 1
  • 1
Rohan Kumar
  • 40,431
  • 11
  • 76
  • 106

1 Answers1

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":"rohan@walkover.in"}, {$push:{"act_mgr.$.sales.agent":"abc@walkover.in"}, $set:{"act_mgr.$.sales.last_interacted":"abc@walkover.in"}})
> db.sales.find().pretty()
{
    "_id" : ObjectId("4f855061dd53351011000b42"),
    "act_mgr" : [
        {
            "sales" : {
                "agent" : [
                    "rohan@walkover.in",
                    "abc@walkover.in"
                ],
                "last_interacted" : "abc@walkover.in"
            }
        }
    ],
    "email" : "aman@asasas.com",
    "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" : ["newdeveloper@walkover.in" ],  "last_interacted" : "newdeveloper@walkover.in" } }}})
> db.sales.find().pretty()
{
    "_id" : ObjectId("4f855061dd53351011000b42"),
    "act_mgr" : [
        {
            "sales" : {
                "agent" : [
                    "rohan@walkover.in",
                    "abc@walkover.in"
                ],
                "last_interacted" : "abc@walkover.in"
            }
        },
        {
            "developer" : {
                "agent" : [
                    "newdeveloper@walkover.in"
                ],
                "last_interacted" : "newdeveloper@walkover.in"
            }
        }
    ],
    "email" : "aman@asasas.com",
    "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" : [
            "rohan@walkover.in",
            "abc@walkover.in"
        ],
        "last_interacted" : "abc@walkover.in"
    },
    {
        "title": "developer",
        "agent" : [
            "newdeveloper@walkover.in"
        ],
        "last_interacted" : "newdeveloper@walkover.in"
    }
]

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":"abc@walkover.in"}, $set:{"act_mgr.$.last_interacted":"abc@walkover.in"}})

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!

Marc
  • 5,488
  • 29
  • 18
  • But I have to update this record by `_id` like `db.sales.update({"_id" : ObjectId("4f855061dd53351011000b42")},{...})` – Rohan Kumar Apr 13 '12 at 04:21
  • 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. – Marc Apr 13 '12 at 14:55