2

Given a mongodb data of

{
    "_id" : ObjectId("552f283dd951e49c6f2f451d"),
    "uuid" : "1-2-1-b95a4040-e29d-11e4-bce8-0381ce4bc8a5",
    "sub" : [ 
        {
            "prod" : 30,
            "var" : 0,
            "status" : "Test",
            "files" : [ 
                {
                    "filePath" : "20150415/2-1/21001429153881552f2859699769.82145796.jpg"
                }, 
                {
                    "filePath" : "20150415/2-1/21001429153880552f28589ca9a8.67013013.jpg"
                }
            ]
        }, 
        {
            "prod" : 10,
            "var" : 0,
            "status" : "Pending",
            "files" : []
        }
    ],
    "process_marker" : 3
}

I would want to update the status of "sub.status" where "uuid" : "1-2-1-b95a4040-e29d-11e4-bce8-0381ce4bc8a5", "sub.prod":10, "sub.prod":0

Normally we'd use the "$" to modify the resulting index as seen below:

use targetDB
db.collection.update({
  "uuid" : "1-2-1-b95a4040-e29d-11e4-bce8-0381ce4bc8a5",
  "sub.prod":10,
  "sub.var":0
},{
  "$set":{"sub.$.status":"MyNewValue"}
})

==== BUT THE CODE ABOVE DOES NOT UPDATE THE CORRECT $ TARGET ====

It updates the "prod":30, "var":0 set... Why is that?

If we limit the query conditions for two key value pairs as seen below, the correct array set is updated

use targetDB
db.collection.update({
  "uuid" : "1-2-1-b95a4040-e29d-11e4-bce8-0381ce4bc8a5",
  "sub.prod":10
},{
  "$set":{"sub.$.status":"MyNewValue"}
})

==== THE CODE ABOVE UPDATES THE CORRECT $ TARGET ====

I'm confused that a more detailed find query would result in updating the wrong array set. Is this a bug or did I do something wrong?

MongoDB version : 3.0.2

andrew
  • 61
  • 1
  • 5

1 Answers1

4

There is no bug in mongoDB, problem in your query is that you used first match "sub.prod":10 and then "sub.var":0 but in updated it takes latest value in your case "sub.var":0 takes and match first matching array where "sub.var":0 that why it updated only "prod" : 30 array element. More ref. click here.

In this case you should use mongo $elemMatch with $and conditions as below

db.collectionName.update({
"uuid": "1-2-1-b95a4040-e29d-11e4-bce8-0381ce4bc8a5",
"sub": {
    "$elemMatch": {
        "$and": [{
            "prod": 10
        }, {
            "var": 0
        }]
    }
}
}, {
"$set": {
    "sub.$.status": "MyNewValue"
}
})
Neo-coder
  • 7,715
  • 4
  • 33
  • 52