MongoDB Push with positional operator not working
I have the following document in the users collection
{
"_id" : "388179687996974",
"matches" : [
{
"userId" : "1495728740672094",
"choice" : false,
"dates" : [],
"dateId" : null
},
{
"userId" : "385516561596016",
"choice" : true,
"dates" : [],
"dateId" : "2014-11-26_385516561596016_388179687996974"
},
{
"userId" : "253752728167114",
"choice" : false,
"dates" : [],
"dateId" : null
},
{
"userId" : "365296866955687",
"choice" : null,
"dates" : [
"2014-11-26"
],
"dateId" : null
}
],
"playDates" : [
"2014-11-26"
]
}
I have the following request
db.users.find({
"_id":{"$ne":"385516561596016"},
"playDates":{"$in":["2014-11-26"]},
"matches":{"$elemMatch":{
"userId":"385516561596016",
"dates":{"$nin":["2014-11-26"]}}}})
It returns the above document.
I am trying to update a document using the positional statement like this:
db.users.update({
"_id":{"$ne":"385516561596016"},
"playDates":{"$in":["2014-11-26"]},
"matches":{"$elemMatch":{"userId":"385516561596016",
"dates":{"$nin":["2014-11-26"]}}}},
{"$push":{"matches.$.dates":"2014-11-26"}})
Instead of putting 2014-11-26 in match for userId 385516561596016, it puts it in matches [0].
What am I doing wrong?
source to share
It smells like a mongodb bug. I've tried a couple of different options.
db.items.update({
"_id":{"$ne":"385516561596016"},
//without the playDates $in clause
"matches":{"$elemMatch":{"userId":"253752728167114"} } } ,
{"$push":{"matches.$.dates":"test"} } )
This works as expected by placing "test" in the third item.
This is not a bug with the $ push operator, as $ set gets confused too:
db.items.update({
"_id":{"$ne":"385516561596016"},
"playDates":{"$in":["2014-11-26"]},
"matches":{"$elemMatch":{"userId":"253752728167114"} } } ,
{"$set":{"matches.$.other":"bob"} } )
//fails
db.items.update({
"_id":{"$ne":"385516561596016"},
"matches":{"$elemMatch":{"userId":"253752728167114"} } } ,
{"$set":{"matches.$.other":"joe"} } )
//success
I think you should report this to JIRA. https://jira.mongodb.org/secure/Dashboard.jspa (If you're lucky they can fix this in a year. So far they've fixed my 1/8 problems).
In the meantime, perhaps you can change your application so that the $ request in the playDates request is not needed?
source to share
The problem is that you are requesting two arrays in one request: playDates
and matches
.
MongoDB is putting your data in matches[0]
because your query matches playDates[0]
with {"$in":["2014-11-26"]}
, so MongoDB binds $
to its index 0.
Unfortunately, I don't know how to fix this without deleting the "playDates":{"$in":["2014-11-26"]}
part.
source to share
The problem is when you are trying to match values ββfrom two different arrays - matches
and playDates
- in the same request document. This is currently not supported in MongoDB.
According to dos :
The request document must contain only one condition for the array Projected field. Multiple conditions can override each other internally and lead to undefined behavior.
According to these requirements, the following query is incorrect:
db.collection.find( { <array>: <value>, <someOtherArray>: <value2> },
{ "<array>.$": 1 } )
Since using $
to update the corresponding document in one of the arrays results in behavior undefined
, the workaround would be to run two queries, one to find the document, the other to update it once the values ββchange in the application code.
source to share