user2814799
user2814799

Reputation: 559

Updating Nested Embedded Documents in mongodb

I am new to mongodb. Plz help me with this.

I need a document like this

  employee{ 
  _id:111,
 name:xxx,
 dependents : [ {
              name:a,
              age:51,
              dep_children:[{name:aa}{name:bb}{name:c}]
              } 

              {
              name:b,
              age:52,
              dep_children:[{name:aa}{name:bb}{name:c}]
              }
              {
              name:c,
              age:51,
              dep_children:[{name:aa}{name:bb}{name:cc}]
               }
              ]
        }

I am using the below script to migrate data for SQL and update it into mongoDB

My code looks something like this:

    while(personcount>=0)

    {  



        BasicDBObject doc = new BasicDBObject("_id",ind1.get(count)).

                append("name",ind2.get(count));

        coll.insert(doc);

       while(dependentcount>0) 
         {


           BasicDBObject querymongo = new BasicDBObject();
                  querymongo.put( "name",ind.get(count));

                      BasicDBObject tenant = new BasicDBObject();
                  tenant.put("name",indsa.get(innercount) );
                  tenant.put("age", indsa2.get(innercount));


                  BasicDBObject update = new BasicDBObject();
                  update.put("$push", new BasicDBObject("dependents",tenant));
                     coll.update(querymongo, update,true,true);
                      while(kidcount>0)
                         {



                    BasicDBObject querymongofact = new BasicDBObject();
                    querymongokid.put(  "dependent.name",indsa.get(innercount));
                      BasicDBObject tenantkid = new BasicDBObject();
                      tenantkid .put("name",indfact.get(innercountfact) );




                      BasicDBObject updatekid = new BasicDBObject();
                      updatekid .put("$push", new BasicDBObject("dependent.dep_children",tenantkid));

                      coll.update(querymongokid, updatekid ,true,true);
                          }
         }
       }

when we print querymongokid and updatekid, the data inside it are expected values itself. This code is not throwing any error. But in data base the only dep_children data is not getting updated . I am not getting wt went wrong. please help me

Thanks in advance

Upvotes: 2

Views: 1275

Answers (1)

chk
chk

Reputation: 534

Your last query fails in the mongo driver in a sense that the update has no effect - but it's not an actual error. Just let me reproduce what you are doing in the mongo shell:

> db.coll.insert({_id:1,name:"name1"})
> db.coll.update({name:"name1"}, {"$push": {dependents: {name:"a", age:50}}})
> db.coll.update({name:"name1"}, {"$push": {dependents: {name:"b", age:55}}})
> db.coll.findOne()
{
        "_id" : 1,
        "dependents" : [
                {
                        "name" : "a",
                        "age" : 50
                },
                {
                        "name" : "b",
                        "age" : 55
                }
        ],
        "name" : "name1"
}
> db.coll.update({"dependents.name": "a"}, {"$push": {"dependents.dep_children": {name:"aa"}}})
can't append to array using string field name: dep_children
> db.coll.update({"dependents.name": "a"}, {"$push": {"dependents.$.dep_children": {name:"aa"}}})
> db.coll.findOne()
{
        "_id" : 1,
        "dependents" : [
                {
                        "age" : 50,
                        "dep_children" : [
                                {
                                        "name" : "aa"
                                }
                        ],
                        "name" : "a"
                },
                {
                        "name" : "b",
                        "age" : 55
                }
        ],
        "name" : "name1"
}

Unfortunately, I have very little experience with the native mongo java driver (I'm usually on Spring data), but changing your line

updatekid.put("$push", new BasicDBObject("dependent.dep_children",tenantkid));

to

updatekid.put("$push", new BasicDBObject("dependent.$.dep_children",tenantkid));

should do the trick as well.

The reason for that behavior is that "dependent.dep_children" is not a valid selector as it corresponds to "go to field dep_children within the subdocument dependent". However, "dependent" happens to be an array without any fields. The $ replaces an explicit index and will make sure the correct subdocument from your query is selected.

Also see here for a less error-prone formulation of your query - without using $elemMatch it will only work if your query uniquely identifies a certain array element. With $elemMatch it will always work, but only update the first match.

Upvotes: 1

Related Questions