如何将pymongo.cursor.Cursor转换为字典?

98

我正在使用pymongo来查询某个区域中的所有项目(实际上是在地图上查询该区域内的所有场馆)。我之前使用过db.command(SON())在球形区域中进行搜索,可以返回一个字典,在字典中有一个名为results的键,其中包含这些场馆。现在我需要在一个正方形区域中搜索,建议我使用db.places.find,但是它返回一个pymongo.cursor.Cursor类,我不知道如何从中提取场馆结果。

有没有人知道我应该将游标转换为字典并提取结果,还是使用另一种方法在正方形区域中查询项目? 顺便说一下,db是pymongo.database.Database类

代码如下:

>>> 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)

我有ll_lng、ll_lat、ur_lng和ur_lat的值,但使用这些值后代码没有输出任何内容。


1
您可以像处理字典列表一样处理返回的pymongo游标。 - dursk
2
@dursk 但是在游标被销毁之前,您只能循环一次游标,因此您需要确保将每个结果保存在字典列表中。 - tim-phillips
8个回答

114

find方法返回一个Cursor实例,允许您迭代所有匹配的文档。

要获取符合给定条件的第一个文档,需要使用find_onefind_one的结果是一个字典。

您始终可以使用list构造函数返回集合中所有文档的列表,但请记住,这将加载所有数据到内存中,可能不是您想要的。

如果您需要重复使用游标并且有充分的理由不使用rewind(),则应该这样做。


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}

使用 find_one 的演示:

>>> col.find_one()
{'a': 1, '_id': ObjectId('54ff30faadd8f30feb90268f'), 'b': 2}

16
+1 您始终可以使用列表构造函数... 这真的很实用。没有任何文档提到过这一点... - Romeo Sierra

92

简单易懂

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)

就是这样啦


天才!谢谢!! - Gs.
'ObjectId'对象不可迭代。 - Robin Mollah

15

我建议创建一个列表,并将字典添加到其中。

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

现在x是一个字典列表,您可以按照通常的Python方式进行操作。


6
这句话的意思是:这个代码可以缩短为[x for x in db.dbname.find()]吗?我的翻译如下:能否将其简写为[x for x in db.dbname.find()]? - jimm101

2

MongoDB的find方法不会返回单个结果,而是以Cursor的形式返回一系列结果。后者是一个迭代器,因此您可以使用for循环遍历它。

对于您的情况,只需使用findOne方法而不是find。这将以字典形式返回单个文档。


我正在尝试更好地理解find()find_one()的结果,那么澄清一下,确定的答案是:Cursor是一个由匹配数据库中文档组成的list of dicts列表吗?例如: cursor = [{"_id" : ObjectId("xxxx"),"tokens" : [ "Python", "Programming"],"area" : "Programming","title" : "Python"},{"_id" : ObjectId("xxxx"),"tokens" : [ "C#", "Programming"],"area" : "Programming","title" : "C#"}] 其中只有通过迭代才能访问值,而find_one()的值是通过方括号表示法访问1个文档的值? - user1063287
实际上,对于那些在寻找答案的人,这里有一个更详细的例子:https://dev59.com/i14b5IYBdhLWcg3wiiV4#28970776 - user1063287

2

Map函数是将大型集合转换的快速方法。

from time import time


cursor = db.collection.find()

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

t1 = time()
blackset = set(map(f, cursor))
print(time() - t1)

0

一行解决方案

[ doc for doc in db.dbname.find({}, {"ID":1, "NAME":1}) ]

0
将其转换为列表将解决问题。
resp = db.places.find({"loc": {"$within": {"$box": [[ll_lng,ll_lat], [ur_lng,ur_lat]]}}})
resp = list(resp)

根据目前的写法,你的回答不够清晰。请编辑以添加更多细节,帮助其他人理解这如何回答所提出的问题。你可以在帮助中心找到更多关于如何撰写好回答的信息。 - undefined

-3

3
在游标上调用 to_dict() 方法实际上不起作用。 - RoyalTS

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接