2014년 12월 8일 월요일

findAndModify bug (v. > 2.6.0)

Hi, I'm developing on MongoDB since v. 2.2 and it's the first time i get this error. I think it's a bug introduced in v. 2.6.0, since I'm not getting it on v. 2.4.10.
db.proximity is an empty collection and I'm executing this query:

db.proximity.findAndModify({query: {'users': {'$all': ['536811da10382f26be2a1b15', '536811da10382f26be2a1b17']}}, update:{'$set': {'last_seen': new Date(), 'users': ['536811da10382f26be2a1b15', '536811da10382f26be2a1b17'], 'users_data': {'536811da10382f26be2a1b15': {'user_name': 'Testola Testa', 'user_id': '1', 'service': 'manager'}, '536811da10382f26be2a1b17': {'user_name': 'Beacon Test', 'user_id': 'Z1234512345', 'service': 'manager'}}}}, upsert: true})
The error i get is:
findAndModifyFailed failed: {
"value" : null,
"errmsg" : "exception: Cannot create base during insert of update. Caused by :ConflictingUpdateOperators Cannot update 'users' and 'users' at the same time",
"code" : 12,
"ok" : 0
} at src/mongo/shell/collection.js:614
Plus, if i execute the same query but without the quotes surrounding '$all', the query is executed well and the result is as expected.
This is the working query:
db.proximity.findAndModify({query: {'users': {$all: ['536811da10382f26be2a1b15', '536811da10382f26be2a1b17']}}, update:{'$set': {'last_seen': new Date(), 'users': ['536811da10382f26be2a1b15', '536811da10382f26be2a1b17'], 'users_data': {'536811da10382f26be2a1b15': {'user_name': 'Testola Testa', 'user_id': '1', 'service': 'manager'}, '536811da10382f26be2a1b17': {'user_name': 'Beacon Test', 'user_id': 'Z1234512345', 'service': 'manager'}}}}, upsert: true})
By the way, my mongodb driver can't execute queries without braces on the keys, so it's a big problem to me, and I'm downgrading to 2.4.



In 2.4 what value did you expect the upserted document to have?
It's technically invalid to query for one value of fieldX and then try to upsert a different value, since queried fields are expected to be in the final document.
I don't see how the upserted document can satisfy the originally query, that's why I'm asking what the result document should look like in your use case.



The expected result has, as you can see, the same value for the field 'users' that is the only queried field. Thus, the problem is not experienced if i remove the quotes (') on $all.
On v 2.4.x it works pretty well.



Walter: thanks for posting about this issue.  I've confirmed this as a regression introduced in MongoDB 2.6 and have filed a bug report. See <https://jira.mongodb.org/browse/SERVER-13843> to track the progress of the fix for this issue, and for information on how to work around it.

I suspect the problem with the quotes around the $all operator is orthogonal, and related to an issue with your programming environment (knowing nothing else, I'd guess that $all is being interpreted as a variable name when it is unquoted in your programming language, in which case your driver would be sending a different field name entirely to the server).

> It's technically invalid to query for one value of fieldX and then try to upsert a different value, since queried fields are expected to be in the final document.
Asya: this isn't the case.  Note that e.g. update({a:1}, {$set: {a: 2}}, {upsert: true}) is and has always been a valid use case for upsert.



Thank you Jason, and sorry Asya for my bad explanation of the issue (it's my bad english).
By the way, Jason, I'm getting this error even running the query from the mongo shell, same version of the core module. You can try yourself and I guess you'll notice it. That's why I didn't include my environment specs.
Thank you again!



Now that I had a chance to test this - I get the same behavior whether
'$all' or $all or "$all" is used (in the shell).

Rassi is right - you can query by one value and $set another, at least
in 2.4 - but it doesn't quite make sense to me...

But by that token wasn't 2.4 doing the wrong thing in the example
given then?  If the final document had the value that was queried for
(rather than the one that was $set?)
Maybe 2.4 had a bug here as well?



Asya: I believe Walter means to say that the before/after values for the "users" field are the same in the example (that is, the $set for that field is a no-op).



Yes, as Jason says the before/after values for "users" are the same. The $set is a no-op in case of update, but since 'upsert' is True, if there isn't a document matching the query, a new one will be created. In this case, 2.4 does that job, while 2.6 raises the reported error.



Up (The issue is still present in 2.6.4)



Me too!



As noted earlier in this thread, Jason filed SERVER-13843 which you can upvote and watch for updates:



Hi Stephen,

Thanks, I see. I was just trying to upvote it here too, because it's not obvious if it has been planed to be fixed or not.




The current state of server issues is reflected in Jira. At the moment SERVER-13843 is still open and the fixVersion of "Needs Triage" indicates that no decision has been made for a target release yet. If you "watch" an issue in Jira you can get notification on any state changes.


댓글 없음:

댓글 쓰기