98

I am using pymongo to query for all items in a region (actually it is to query for all venues in a region on a map). I used db.command(SON()) before to search in a spherical region, which can return me a dictionary and in the dictionary there is a key called results which contains the venues. Now I need to search in a square area and I am suggested to use db.places.find, however, this returns me a pymongo.cursor.Cursor class and I have no idea how to extract the venue results from it.

Does anyone know whether I should convert the cursor into a dict and extract the results out, or use another method to query for items in a square region? BTW, db is pymongo.database.Database class

The code is:

>>> import pymongo
>>> db = pymongo.MongoClient(host).PSRC 
>>> resp = db.places.find({"loc": {"$within": {"$box": [[ll_lng,ll_lat], [ur_lng,ur_lat]]}}})
>>> for doc in resp:
>>>     print(doc)

I have values of ll_lng, ll_lat, ur_lng and ur_lat, use these values but it prints nothing from this codes

starball
  • 20,030
  • 7
  • 43
  • 238
gladys0313
  • 2,569
  • 6
  • 27
  • 51
  • 1
    You can treat the pymongo cursor that is returned the same way you'd treat a list of dictionaries. – dursk Mar 10 '15 at 16:32
  • 2
    @dursk But you can only cycle through the cursor once before the cursor is destroyed, so you'd need to make sure to save each result in a list of dicts. – tim-phillips Apr 06 '16 at 23:32

7 Answers7

113

The find method returns a Cursor instance, which allows you to iterate over all matching documents.

To get the first document that matches the given criteria, you need to use find_one. The result of find_one is a dictionary.

You can always use the list constructor to return a list of all the documents in the collection but bear in mind that this will load all the data in memory and may not be what you want.

You should do that if you need to reuse the cursor and have a good reason not to use rewind()


Demo using find:

>>> import pymongo
>>> conn = pymongo.MongoClient()
>>> db = conn.test #test is my database
>>> col = db.spam #Here spam is my collection
>>> cur = col.find()  
>>> cur
<pymongo.cursor.Cursor object at 0xb6d447ec>
>>> for doc in cur:
...     print(doc)  # or do something with the document
... 
{'a': 1, '_id': ObjectId('54ff30faadd8f30feb90268f'), 'b': 2}
{'a': 1, 'c': 3, '_id': ObjectId('54ff32a2add8f30feb902690'), 'b': 2}

Demo using find_one:

>>> col.find_one()
{'a': 1, '_id': ObjectId('54ff30faadd8f30feb90268f'), 'b': 2}
styvane
  • 59,869
  • 19
  • 150
  • 156
  • 16
    +1 *You can always use the list constructor...* this was a life saver. No document mentioned anything about this... – Romeo Sierra May 19 '19 at 07:25
92

Easy

import pymongo
conn = pymongo.MongoClient()
db = conn.test #test is my database
col = db.spam #Here spam is my collection
array = list(col.find())

print(array)

There you go

jtlz2
  • 7,700
  • 9
  • 64
  • 114
Aminah Nuraini
  • 18,120
  • 8
  • 90
  • 108
15

I suggest create a list and append dictionary into it.

x   = []
cur = db.dbname.find()
for i in cur:
    x.append(i)
print(x)

Now x is a list of dictionary, you can manipulate the same in usual python way.

Merlin
  • 24,552
  • 41
  • 131
  • 206
2

The MongoDB find method does not return a single result, but a list of results in the form of a Cursor. This latter is an iterator, so you can go through it with a for loop.

For your case, just use the findOne method instead of find. This will returns you a single document as a dictionary.

Alexandre
  • 1,635
  • 14
  • 21
  • I am trying to get a better visual understanding of what `find()` and `find_one()` results look like, so to clarify, is the definitive answer that: a `Cursor` is a `list` of `dicts` which represents a list of matched documents from the database? eg: `cursor = [{"_id" : ObjectId("xxxx"),"tokens" : [ "Python", "Programming"],"area" : "Programming","title" : "Python"},{"_id" : ObjectId("xxxx"),"tokens" : [ "C#", "Programming"],"area" : "Programming","title" : "C#"}]` where values are only accessible through iteration, whereas `find_one()` values from 1 doc are accessed through bracket notation? – user1063287 Jul 27 '16 at 11:38
  • Actually, for those looking, there is an answer here that gives a more detailed example as well: http://stackoverflow.com/a/28970776/1063287 – user1063287 Jul 27 '16 at 11:47
2

Map function is fast way to convert big collection

from time import time


cursor = db.collection.find()

def f(x):
    return x['name']

t1 = time()
blackset = set(map(f, cursor))
print(time() - t1)
Rafal
  • 573
  • 5
  • 11
0

One Line Solution

[ doc for doc in db.dbname.find({}, {"ID":1, "NAME":1}) ]
RAHUL GUPTA
  • 91
  • 1
  • 3
-3

to_dict() Convert a SON document to a normal Python dictionary instance.

This is trickier than just dict(...) because it needs to be recursive.

http://api.mongodb.org/python/current/api/bson/son.html

Yegor Dia
  • 61
  • 1
  • 8