mcadio
mcadio

Reputation: 769

removing object from nested array of objects mongodb

I've got collection with volunteer information in it, and it lists the volunteers as an array of objects. I can display all the shifts for each volunteer, but removing one from the array is proving difficult for me:

Sample data:

"_id" : ObjectId("59180305c19dbaa4ecd9ee59"),
    "where" : "Merchandise tent",
    "description" : "Sell gear at the merchandise tent.",
    "shifts" : [
            {
                    "dateNeeded" : ISODate("2017-06-23T00:00:00Z"),
                    "timeslot" : "8:00 - NOON",
                    "needed" : 2,
                    "_id" : ObjectId("591807546a71c3a57d1a2105"),
                    "volunteers" : [
                            {
                                    "fullname" : "Mary Mack",
                                    "phone" : "1234567890",
                                    "email" : "[email protected]",
                                    "_id" : ObjectId("591ce45bc7e8a8c7b742474c")
                            }
                    ]
            },

The data I have available for this is: _id, where, shifts.timeslot, shifts.dateNeeded, volunteers.email

Can someone help me? Lets say Mary Mack wants to unVolunteer for the 8 - Noon shift at the merchandise tent. She may be listed under other shifts as well, but we only want to remove her from this shift.

Upvotes: 3

Views: 3090

Answers (2)

Neil Lunn
Neil Lunn

Reputation: 151112

You can do this by specifying something to match the "document" and then the required "shifts" array entry as the query expression for an .update(). Then apply the positional $ operator for the matched array index with $pull:

db.collection.update(
 { "_id": ObjectId("59180305c19dbaa4ecd9ee59"), "shifts.timeslot": "8:00 - NOON" },
 { "$pull": { "shifts.$.volunteers": { "fullname": "Mary Mack" } } }
)

That is okay in this instance since you are only trying to "match" on the "outer" array in the nested structure and the $pull has query arguments of it's own to identify the array entry to remove.

You really should be careful using "nested arrays" though. As whilst a $pull operation like this works, updates to the "inner" array are not really possible since the positional $ operator will only match the "first" element that meets the condition. So your example of "Mary Mack" in multiple shifts would only ever match in the first "shifts" array entry found.

Upvotes: 4

Kenneth Solilapsi
Kenneth Solilapsi

Reputation: 11

Try this

db.example.update(
 {},
 { $unset: {"Mary Mack":1}},
 false, true
)

Upvotes: 1

Related Questions