mongodb update not working on nested subdocument

665 Views Asked by At

My mongodb records are like in this link Updating nested array inside array mongodb and sample records are as below and want to update a field in the nested document "parameter" array provided it satisfies some conditions (_id : "04", operations._id : "100" and operations.parameters.pid : "012"), this update query UPDATES wrong nested record (operations.parameters.pid : '011') , please help where I am going wrong:

       {
"_id" : "04",
"name" : "test service 4",
"id" : "04",
"version" : "0.0.1",
"title" : "testing",
"description" : "test",
"protocol" : "test",
"operations" : [ 
    {
        "_id" : "99",
        "oName" : "test op 52222222222",
        "sid" : "04",
        "name" : "test op 52222222222",
        "oid" : "99",
        "description" : "testing",
        "returntype" : "test",
        "parameters" : [ 
            {
                "oName" : "Param1",
                "name" : "Param1",
                "pid" : "011",
                "type" : "582",
                "description" : "testing",
                "value" : "",
                "version" : 1.0
            }, 
            {
                "oName" : "Param2",
                "name" : "Param2",
                "pid" : "012",
                "type" : "58222",
                "description" : "testing",
                "value" : "",
                "version" : 2.0
            }
        ]
    }, 
    {
        "_id" : "100",
        "oName" : "test op 909090",
        "sid" : "05",
        "name" : "test op 90909",
        "oid" : "1009",
        "description" : "testing",
        "returntype" : "test",
        "parameters" : [ 
            {
                "oName" : "Param1",
                "name" : "Param1",
                "pid" : "011",
                "type" : "582",
                "description" : "testing",
                "value" : "",
                "version" : 1.0
            }, 
            {
                "oName" : "Param2",
                "name" : "Param2",
                "pid" : "012",
                "type" : "58222",
                "description" : "testing",
                "value" : "",
                "version" : 2.0
            }
        ]
    }, 
    {
        "_id" : "101",
        "oName" : "test op 52222222222",
        "sid" : "04",
        "name" : "test op 52222222222",
        "oid" : "99",
        "description" : "testing",
        "returntype" : "test",
        "parameters" : [ 
            {
                "oName" : "Param1",
                "name" : "Param1",
                "pid" : "011",
                "type" : "582",
                "description" : "testing",
                "value" : "",
                "version" : 1.0
            }, 
            {
                "oName" : "Param2",
                "name" : "Param2",
                "pid" : "012",
                "type" : "58222",
                "description" : "testing",
                "value" : "",
                "version" : 1.0
            }
        ]
    }, 
    {
        "_id" : "102",
        "oName" : "test op 909090",
        "sid" : "05",
        "name" : "test op 90909",
        "oid" : "1009",
        "description" : "testing",
        "returntype" : "test",
        "parameters" : [ 
            {
                "oName" : "Param1",
                "name" : "Param1",
                "pid" : "011",
                "type" : "582",
                "description" : "testing",
                "value" : "",
                "version" : 1.0
            }, 
            {
                "oName" : "Param2",
                "name" : "Param2",
                "pid" : "012",
                "type" : "58222",
                "description" : "testing",
                "value" : "",
                "version" : 2.0
            }
        ]
    }
]
   }

My update query is as follows :

 db.foo.update(
{ $and : [{'_id':'04'},
{'operations._id':'100' },
{'operations.parameters.pid': '012'}]},
{
    "$set": { 
        "operations.1.parameters.$.dummy": "foo"
    }
}
     )

I am using mongodb 3.6.2 referred to https://docs.mongodb.com/master/reference/operator/update/positional-filtered/ Sample record from this link :

   {
"_id" : 1.0,
"grades" : [ 
    {
        "type" : "quiz",
        "questions" : [ 
            10.0, 
            8.0, 
            5.0
        ]
    }, 
    {
        "type" : "quiz",
        "questions" : [ 
            8.0, 
            9.0, 
            6.0
        ]
    }, 
    {
        "type" : "hw",
        "questions" : [ 
            5.0, 
            4.0, 
            3.0
        ]
    }, 
    {
        "type" : "exam",
        "questions" : [ 
            25.0, 
            10.0, 
            23.0, 
            0.0
        ]
    }
]
   }

Example from this link

   db.student3.update(
   {},
        { $inc: { "grades.$[t].questions.$[score]": 2 } },
     { arrayFilters: [ { "t.type": "quiz" } , { "score": { $gte: 8 } } ], multi: true}
      )

ERror I got from robo-3t :

 cannot use the part (grades of grades.$[t].questions.$[score]) to traverse the element ({grades: [ { type: "quiz", questions: [ 10.0, 8.0, 5.0 ] }, { type: "quiz", questions: [ 8.0, 9.0, 6.0 ] }, { type: "hw", questions: [ 5.0, 4.0, 3.0 ] }, { type: "exam", questions: [ 25.0, 10.0, 23.0, 0.0 ] } ]})

Please help; Regards Kris

1

There are 1 best solutions below

1
Atish On

In your update operation

"$set": { 
        "operations.1.parameters.$.dummy": "foo"
    }

refers to the 1st element in operations that is an element with "_id" : "100", and within parameters array, the $ updates the first element in array.

You need to consider using mongodb 3.6 if you want to update nested array elements using $[] to update all matching elements.

One possible way to do this in 3.4 version is fetching the required sub-document and do matches and updates on the application side.