Brett
Brett

Reputation: 12007

How to convert a MongoDB find() query to a PyMongo dictionary?

I am successfully using PyMongo to connect and query (or rather find()) documents in my MongoDB collection.

However, I'm running into an issue. Using the MongoDB interface, I can execute the command:

db.mycollection.find({ $and: [{filename: {$regex: '\\.part_of_my_name'} }, {bases: {$gt: 10000 } } ] } )

And it works great. However, when I try to execute this command in PyMongo, I see that the PyMongo declaration for find() requires a Python dict object only. It actually raises an exception if a string is provided.

So my question is: how can I convert the above JSON(?) string to a dictionary?

I tried building it manually, but it's overly complicated, and I'm wondering if there is a simple way to go from string to dictionary.

Upvotes: 0

Views: 2777

Answers (1)

Rob Watts
Rob Watts

Reputation: 7146

To go from a string to a dictionary, you can use json.loads:

>>> import json
>>> json.loads('{"key":"value"}')
{'key': 'value'}

However, you cannot always copy and paste a MongoDB command and expect it to be valid json. For example:

>>> json.loads('{$and: [{filename: {$regex: "\\.part_of_my_name"} }, {bases: {$gt: 10000 }}]}')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 338, in loads
    return _default_decoder.decode(s)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 365, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 381, in raw_decode
    obj, end = self.scan_once(s, idx)
ValueError: Expecting property name: line 1 column 2 (char 1)

In order for it to work in Python, all of the keys need to be explicitly quoted. So $and needs to become "$and". Also, you'll have to use additional escapes for backslashes (kinda ugly, I know).

The query in your example should look like this:

jsonString = '{"$and":[{"filename":{"$regex":"\\\\.part_of_my_name"}},{"bases":{"$gt":10000}}]}'

You can then use json.loads on it. However, At this point it is a valid Python dictionary, so you could just use this:

jsonDict = {"$and":[{"filename":{"$regex":"\\.part_of_my_name"}},{"bases":{"$gt":10000}}]}

Upvotes: 3

Related Questions