I believe there is a bug in pymongo (or, at least, the documentation) which makes it impossible to run a findandupdate
query.
Here's what happens. When I run:
result = db.command({
'findandmodify': 'my_collection',
'query': {'foo': 'bar'},
'update': {'$set': {'status': 'queued'}},
})
The query that actually gets sent to the server is:
{ 'query': {'foo': 'bar'}, 'findandmodify': 'my_collection', … }
Note that the query
argument is first, and findandmodify
is second.
But this causes the 开发者_StackOverflow社区server to throw up:
OperationFailure: command { 'query': {'foo': 'bar'}, 'findandmodify': 'my_collection', … } failed: no such cmd
Because the server expects findandmodify
to be first (BSON dicts are, apparently, ordered).
Is there any work around for this?
For languages that don't have a built-in sorted dict type the mongo drivers include one. In python that is the SON type: http://api.mongodb.org/python/1.4%2B/api/pymongo/son.html. You will need to use that for all commands.
If that still fails make sure you are using the latest version of the database as findandmodify is a new feature.
current pymongo api has find_and_modify built-in see more at https://github.com/mongodb/mongo-python-driver/blob/master/pymongo/collection.py#L1035
One workaround may be to construct the JavaScript version of the command and pass it to db.eval().
db.eval('db.runCommand({"findandmodify": "my_collection", "query": {"foo": "bar"}, "update": {"$set": {"status": "queued"}},})')
The issue is that, as Alex mentioned, Python dicts have no order, so you will need to build the string more-or-less manually.
See PyMongo documentation:
Note the order of keys in the command document is significant (the “verb” must come first), so commands which require multiple keys (e.g. findandmodify) should use an instance of SON or a string and kwargs instead of a Python dict.
http://api.mongodb.org/python/2.1/api/pymongo/database.html
精彩评论