1

I want to add members to a an array in a subdocument in MongoDB, and if the subdocument itself does not exist, I wish to create it. Take the following:

{
    curvename: "France",
    dates: [
        {
            date: "2014-07-01",
            members: ["m1", "m2", "m3"]
        },
        {
            date: "2014-07-02",
            members: ["m1", "m2", "m3"]
        },
        {
            date: "2014-07-03",
            members: ["m1", "m2", "m3"]
        }
    ]
}

now I want to add to "m4", and "m5" to each dates, but also include "2014-07-04", so I want to add this:

    dates:  [{
                date: "2014-07-01",
                members: ["m4", "m5"]
            },
            {
                date: "2014-07-02",
                members: ["m4", "m5"]
            },
            {
                date: "2014-07-03",
                members: ["m4", "m5"]
            },
            {
                date: "2014-07-04",
                members: ["m4", "m5"]
            }]

to get this:

{
    curvename: "France",
    dates: [
        {
            date: "2014-07-01",
            members: ["m1", "m2", "m3", "m4", "m5"]
        },
        {
            date: "2014-07-02",
            members: ["m1", "m2", "m3", "m4", "m5"]
        },
        {
            date: "2014-07-03",
            members: ["m1", "m2", "m3", "m4", "m5"]
        },
        {
            date: "2014-07-04",
            members: ["m4", "m5"]
        }

    ]
}

Can this be done in one query?

I am trying all sorts of permutations of $each, $addToSet, and $set, with Upsert, so far with no luck. Here is what I currently have (pymongo):

for d in daterange:
    curves.update({"curvename":curvename}, \
    {"$addToSet": {"date": d, "members": {"$each": members}}},
            upsert = True)

This is adding all the dates, but the members only once at the end. Completely wrong.

Can the above be done in one query? How do I add the new members to each of my dates, but where the dates do not exist, create them and add the members?

I'd prefer a pymongo solution but mongo console will do fine too.

Thomas Browne
  • 23,824
  • 32
  • 78
  • 121

2 Answers2

2

With general variable length arrays, you can't do this in MongoDB at present (2.6). Updates to arrays need to target specific array elements using either $ positional operator or concrete indexes.

wdberkeley
  • 11,531
  • 1
  • 28
  • 23
0

try this : db.curves.update({'curvename': "France"}, {$push: { "dates.0.members" : "m1"}})

the above query can add m1 to members array and will be like members: [ "m1","m4","m5"]

check this link: Mongodb update deeply nested subdocument also read comments section

Community
  • 1
  • 1
  • What about if I wish to add to a dates other than the first one? Will this "0" index ("dates.0.members") not always add to the first one? Or do I need a separate query of some kind? – Thomas Browne Aug 05 '14 at 23:50
  • i didnt understand 'not always add to first one' ? but if you want to ignore the first one you can ignore it while you loop thru it. – user3801556 Aug 06 '14 at 09:24