Hide
Insert this test document:
db.test.insert({
"_id" : NumberLong("1046644416921"),
"teachers" : [
{ "lid" : 203745 },
{ "lid" : 5551146 }
],
"asn" : [
{ "_id" : ObjectId("5b5a4a2cf3c2c0aad9e6237b") },
{ "_id" : ObjectId("5b5a4abdf3c2c0aad9e62382") },
{ "_id" : ObjectId("5b5a4c30f3c2c0aad9e62389") }
]
})
Issue the following update:
db.test.update({ "asn._id" : new ObjectId("5b5a4a2cf3c2c0aad9e6237b"), "teachers.lid" : 5551146 , "_id" : 1046644416921 },
{ "$inc" : { "asn.$.mods" : 1 } })
Expected output of db.test.findOne()
{
"_id" : NumberLong("1046644416921"),
"teachers" : [
{
"lid" : 203745
},
{
"lid" : 5551146
}
],
"asn" : [
{
"_id" : ObjectId("5b5a4a2cf3c2c0aad9e6237b")
"mods" : 1
},
{
"_id" : ObjectId("5b5a4abdf3c2c0aad9e62382"),
},
{
"_id" : ObjectId("5b5a4c30f3c2c0aad9e62389")
}
]
}
Actual output:
{
"_id" : NumberLong("1046644416921"),
"teachers" : [
{
"lid" : 203745
},
{
"lid" : 5551146
}
],
"asn" : [
{
"_id" : ObjectId("5b5a4a2cf3c2c0aad9e6237b")
},
{
"_id" : ObjectId("5b5a4abdf3c2c0aad9e62382"),
"mods" : 1
},
{
"_id" : ObjectId("5b5a4c30f3c2c0aad9e62389")
}
]
}
Notice the wrong sub-document was updated!
Also, please note that if we do this query, we have the same problem.
db.test.update({ "asn" : {$elemMatch:{ _id:new ObjectId("5b5a4a2cf3c2c0aad9e6237b")}},
"teachers.lid" : 5551146 ,
"_id" : 1046644416921 },
{ "$inc" : { "asn.$.mods" : 1 } })
However, if you remove the "teachers.lid" from the query, it behaves as expected. Also, if you do it with the "new-style" array filters, it works perfectly:
db.test.update({ "asn" : { $elemMatch:{_id:new ObjectId("5b5a4a2cf3c2c0aad9e6237b")}},
"teachers.lid" : 5551146,
"_id" : 1046644416921 },
{ "$inc" : { "asn.$[element].mods" : 1 } },
{ arrayFilters:[{ 'element._id': new ObjectId("5b5a4a2cf3c2c0aad9e6237b") }]})
Show
Insert this test document:
db.test.insert({
"_id" : NumberLong( "1046644416921" ),
"teachers" : [
{ "lid" : 203745 },
{ "lid" : 5551146 }
],
"asn" : [
{ "_id" : ObjectId( "5b5a4a2cf3c2c0aad9e6237b" ) },
{ "_id" : ObjectId( "5b5a4abdf3c2c0aad9e62382" ) },
{ "_id" : ObjectId( "5b5a4c30f3c2c0aad9e62389" ) }
]
})
Issue the following update:
db.test.update({ "asn._id" : new ObjectId( "5b5a4a2cf3c2c0aad9e6237b" ), "teachers.lid" : 5551146 , "_id" : 1046644416921 },
{ "$inc" : { "asn.$.mods" : 1 } })
Expected output of db.test.findOne()
{
"_id" : NumberLong( "1046644416921" ),
"teachers" : [
{
"lid" : 203745
},
{
"lid" : 5551146
}
],
"asn" : [
{
"_id" : ObjectId( "5b5a4a2cf3c2c0aad9e6237b" )
"mods" : 1
},
{
"_id" : ObjectId( "5b5a4abdf3c2c0aad9e62382" ),
},
{
"_id" : ObjectId( "5b5a4c30f3c2c0aad9e62389" )
}
]
}
Actual output:
{
"_id" : NumberLong( "1046644416921" ),
"teachers" : [
{
"lid" : 203745
},
{
"lid" : 5551146
}
],
"asn" : [
{
"_id" : ObjectId( "5b5a4a2cf3c2c0aad9e6237b" )
},
{
"_id" : ObjectId( "5b5a4abdf3c2c0aad9e62382" ),
"mods" : 1
},
{
"_id" : ObjectId( "5b5a4c30f3c2c0aad9e62389" )
}
]
}
Notice the wrong sub-document was updated!
Also, please note that if we do this query, we have the same problem.
db.test.update({ "asn" : {$elemMatch:{ _id: new ObjectId( "5b5a4a2cf3c2c0aad9e6237b" )}},
"teachers.lid" : 5551146 ,
"_id" : 1046644416921 },
{ "$inc" : { "asn.$.mods" : 1 } })
However, if you remove the "teachers.lid" from the query, it behaves as expected. Also, if you do it with the "new-style" array filters, it works perfectly:
db.test.update({ "asn" : { $elemMatch:{_id: new ObjectId( "5b5a4a2cf3c2c0aad9e6237b" )}},
"teachers.lid" : 5551146,
"_id" : 1046644416921 },
{ "$inc" : { "asn.$[element].mods" : 1 } },
{ arrayFilters:[{ 'element._id' : new ObjectId( "5b5a4a2cf3c2c0aad9e6237b" ) }]})