0

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

chiku
  • 485
  • 2
  • 8
  • 23
  • What is your version ? – s7vr Jan 26 '18 at 16:31
  • Possible duplicate of [Updating a Nested Array with MongoDB](https://stackoverflow.com/questions/23577123/updating-a-nested-array-with-mongodb) – s7vr Jan 26 '18 at 16:32
  • mongodb version 3.4.3 – chiku Jan 26 '18 at 16:33
  • Its not possible to update arrays nested more than 1 level in old version. Can you update to 3.6 ? – s7vr Jan 26 '18 at 16:35
  • but may I know the reason why its updating wrong record please – chiku Jan 26 '18 at 16:37
  • Sure. You have two array filters `{'operations._id':'100' }, {'operations.parameters.pid': '012'}`. Last index (0) is overriding the other index(1) when you query to find matched index. So `$` finds the match with last one which output index 0 because there is a match in first array element and updates the array element with wrong index. So you have to update to 3.6 to make it work. – s7vr Jan 26 '18 at 16:57

1 Answers1

0

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.

Atish
  • 4,277
  • 2
  • 24
  • 32