Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-39783

Updating Element in the Array using the positional $ operator

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: 3.6.2
    • Component/s: Internal Code
    • None
    • ALL
    • Hide
      • Steps to reproduce the problem
      • Steps to show changing field name makes it work as expected. Note the only change is array element field name is changed from "s" to "a"

      Tried on MongoDB server version: 3.6.2

      Steps to reproduce the problem.

      // code placeholder
      > db.mycoll.insert({"_id":1, "arr":[{"s": "ABC", "c":"123", "count": 1}, {"s": "ABC", "c":"12345", "count": 2}]})
      
      WriteResult({ "nInserted" : 1 })
      
      > db.mycoll.find().pretty()> db.mycoll.find().pretty()
      { 
           "_id" : 1, 
           "arr" : [ 
                     { 
                       "s" : "ABC", 
                       "c" : "123", 
                       "count" : 1 
                     }, 
                     { 
                       "s" : "ABC", 
                       "c" : "12345", 
                       "count" : 2 
                     } 
                 ]
      }
      
      > db.mycoll.update({ "_id" : 1, "arr.s": "ABC", "arr.c":"12345"}, { "$set" : { "arr.$" : { "s" : "ABC", "c" : "12345", "count" : 5 }}})
      
      WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
      
      > db.mycoll.find().pretty()
      
      {
      	"_id" : 1,
      	"arr" : [
      		{
      		  "s" : "ABC",
                        "c" : "12345", // *** wrong array element updated
                        "count" : 5   // *** wrong array element updated
                       },
                       {
                         "s" : "ABC",
                         "c" : "12345",
                         "count" : 2
                        }
                       ]
      }
      
      

       

      Steps to show changing field name makes it work as expected. Note the only change is array element field name is changed from "s" to "a"

      > db.mycoll.insert({"_id":1, "arr":[{"a": "ABC", "c":"123", "count": 1}, {"a": "ABC", "c":"12345", "count": 2}]})
      
      WriteResult({ "nInserted" : 1 })
      
      > db.mycoll.find().pretty()
      { 
             "_id" : 1, 
             "arr" : [ 
                       { 
                         "a" : "ABC", 
                         "c" : "123", 
                         "count" : 1 
                       }, 
                       { 
                         "a" : "ABC", 
                         "c" : "12345", 
                         "count" : 2 
                        } 
                      ]
      }
      
      > db.mycoll.update({ "_id" : 1, "arr.a": "ABC", "arr.c":"12345"}, { "$set" : { "arr.$" : { "a" : "ABC", "c" : "12345", "count" : 5 }}})
      
      WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
      
      > db.mycoll.find().pretty()
      
      { 
             "_id" : 1, 
             "arr" : [ 
                       { 
                         "a" : "ABC", 
                         "c" : "123", 
                         "count" : 1 
                       }, 
                       { 
                        "a" : "ABC", 
                        "c" : "12345", // *** correctly updated
                        "count" : 5 // *** correctly updated
                       } 
                     ]
      }

       

       

       

      Show
      Steps to reproduce the problem Steps to show changing field name makes it work as expected. Note the only change is array element field name is changed from "s" to "a" Tried on MongoDB server version: 3.6.2 Steps to reproduce the problem. // code placeholder > db.mycoll.insert({ "_id" :1, "arr" :[{ "s" : "ABC" , "c" : "123" , "count" : 1}, { "s" : "ABC" , "c" : "12345" , "count" : 2}]}) WriteResult({ "nInserted" : 1 }) > db.mycoll.find().pretty()> db.mycoll.find().pretty() { "_id" : 1, "arr" : [ { "s" : "ABC" , "c" : "123" , "count" : 1 }, { "s" : "ABC" , "c" : "12345" , "count" : 2 } ] } > db.mycoll.update({ "_id" : 1, "arr.s" : "ABC" , "arr.c" : "12345" }, { "$set" : { "arr.$" : { "s" : "ABC" , "c" : "12345" , "count" : 5 }}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.mycoll.find().pretty() { "_id" : 1, "arr" : [ { "s" : "ABC" , "c" : "12345" , // *** wrong array element updated "count" : 5 // *** wrong array element updated }, { "s" : "ABC" , "c" : "12345" , "count" : 2 } ] }   Steps to show changing field name makes it work as expected. Note the only change is array element field name is changed from "s" to "a" > db.mycoll.insert({"_id":1, "arr":[{"a": "ABC", "c":"123", "count": 1}, {"a": "ABC", "c":"12345", "count": 2}]}) WriteResult({ "nInserted" : 1 }) > db.mycoll.find().pretty() { "_id" : 1, "arr" : [ { "a" : "ABC", "c" : "123", "count" : 1 }, { "a" : "ABC", "c" : "12345", "count" : 2 } ] } > db.mycoll.update({ "_id" : 1, "arr.a": "ABC", "arr.c":"12345"}, { "$set" : { "arr.$" : { "a" : "ABC", "c" : "12345", "count" : 5 }}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.mycoll.find().pretty() { "_id" : 1, "arr" : [ { "a" : "ABC", "c" : "123", "count" : 1 }, { "a" : "ABC", "c" : "12345", // *** correctly updated "count" : 5 // *** correctly updated } ] }      

      MongoDB Update is working inconsistently when using the positional $ operator to update an array element. It seems to be always updating the first element and not the element matching the query condition.

      Found that update is working as expected when the array element field name is changed from "s" to "a". Please see steps to reproduce for more details.

      Found the issue on MongoDB server version: 3.6.2. Not sure if it is present in all versions.

            Assignee:
            eric.sedor@mongodb.com Eric Sedor
            Reporter:
            venkateshcm Venkatesh
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: