Python 如何检查pymongo游标是否有查询结果
我需要检查Python 如何检查pymongo游标是否有查询结果,python,mongodb,pymongo,mongodb-query,Python,Mongodb,Pymongo,Mongodb Query,我需要检查find语句是否返回非空查询 我所做的是: query = collection.find({"string": field}) if not query: #do something 然后我意识到我的if语句从未执行过,因为find返回一个游标,要么查询是空的,要么不是空的 因此,我检查了,发现有两种方法可以帮助我: 计数(带限制和跳过=假)其中(根据说明): 返回此查询结果集中的文档数 这似乎是检查的好方法,但这意味着我需要数数 游标中的所有结果都是为了知道它是否为零,对吗?有点
find
语句是否返回非空查询
我所做的是:
query = collection.find({"string": field})
if not query: #do something
然后我意识到我的if
语句从未执行过,因为find
返回一个游标,要么查询是空的,要么不是空的
因此,我检查了,发现有两种方法可以帮助我:
计数(带限制和跳过=假)
其中(根据说明):
返回此查询结果集中的文档数
这似乎是检查的好方法,但这意味着我需要数数
游标中的所有结果都是为了知道它是否为零,对吗?有点贵已检索
其中(从描述中):
到目前为止检索到的文档数
我在一个空查询集上测试了它,它返回零,但不是
清楚它的作用,我不知道它是否适合我find()
查询是否返回空集的最佳方法(最佳实践)是什么?上述方法之一是否适用于此目的?那么性能呢?还有其他方法吗
只是想澄清一下:我需要知道查询是否为空,并且我想找到关于性能和pythonic的游标的最佳方式。编辑:虽然2014年是这样,但现代版本的pymongo和MongoDB已经改变了这种行为。买家注意:
.count()
是查找查询中返回的结果数的正确方法。count()
方法不会耗尽游标的迭代器,因此可以在迭代结果集中的项之前安全地执行.count()
检查
MongoDB 2.4中的计数方法的性能得到了极大的改进。唯一可以减慢计数的事情是查询是否设置了索引。要确定查询中是否有索引,可以执行以下操作
query = collection.find({"string": field})
print query.explain()
如果在结果中看到BasicCursor
,则需要在string
字段上为该查询创建索引
EDIT:正如@alvapan指出的,pymongo 3.7+中的方法现在更倾向于在单独的查询中使用count\u文档
item_count = collection.count_documents({"string": field})
计算查询返回的项数的正确方法是,在迭代查询后检查查询上的.retrieved
计数器,或者首先对查询进行枚举:
# Using .retrieved
query = collection.find({"string": field})
for item in query:
print(item)
print('Located {0:,} item(s)'.format(query.retrieved))
或者,另一种方式:
# Using the built-in enumerate
query = collection.find({"string": field})
for index, item in enumerate(query):
print(item)
print('Located {0:,} item(s)'.format(index+1))
用find_one
代替find
怎么样?然后,您只需检查您是否得到了结果或None
。如果“string”被索引,您可以传递字段={“string”:1,“\u id”:0}
,从而使其成为一个仅索引的查询,这会更快。根据我的测试,最快的方法是
if query.first():
# do something
In [51]: %timeit query = MyMongoDoc.objects(); query.first()
100 loops, best of 3: 2.12 ms per loop
In [52]: %timeit query = MyMongoDoc.objects(); query.count()
100 loops, best of 3: 4.28 ms per loop
(使用MongoDB 2.6.72015-03-26)另一种解决方案是将光标转换为列表,如果光标没有任何数据,则空列表或列表包含所有数据
doc_list = collection.find({}); #find all data
have_list = True if len(list(doc_list)) else False;
那要看你想用什么了it@VincentBeltman我只需要知道查询是否使用该游标返回某些内容。您已经在集合中执行了该查询。find()方法。“count”方法只是返回find方法返回给游标的文档数。您只需执行“if query.count>0:”@vintastic我理解,但性能如何?count
是否需要重新扫描找到的所有结果以给我一个数字?@boh光标是指向查询结果集的指针。因此,重新扫描是不必要的。字段string
是索引的,但我不能使用findOne
,因为不能保证只有一个结果(实际上不太可能有一个)。在我的理解中,您只想知道您是否有任何查询结果,对吗?如果是这种情况,那么find_one就足够了:如果它返回一个值,这意味着find()将至少找到一个结果,如果它返回None
,这意味着find()将返回0个结果。是的,但是如果没有结果,我将做一些事情,否则我将对结果做一些事情,并临时显示所有结果。您是否认为在索引字段上使用findOne
进行查询更有效?如果该字段不是空的,则使用find
再次执行查询?另一种选择:只需迭代结果并执行您的操作。如果没有结果,它将是一个空循环,您可以使用代码中的标志(在循环中将标志设置为True)来检测它。似乎行查找比查找快得多。看:谢谢你提起这件事,伙计。count()是检查非空查询的完美函数。我遇到了类似的问题,并通过此函数得到了解决。@VoodoonFX,PyMongo 3.7已弃用cursor.count(),并要求我们改用collection.count\u documents()。然后我不知道找到游标中返回的结果数量的新的正确方法是什么。我们是否需要collection.count\u documents(query\u string)
首先检查数字,然后collection.find(query\u string)
以获得真正的结果?但新方法要求我们做两次查询,而旧方法只做一次,这似乎更好。@AlvaPan编辑了回复,谢谢。就我个人而言,我更喜欢只执行查询,然后清点文档。没有多少可扩展的解决方案应该使用count方法提前知道他们正在查询多少文档,除了集合用例中的文档总数。我也喜欢这种方法,但这种方法的缺点是list()函数会耗尽游标。最好使用它,当你确信你的游标包含相对少量的文档时,列表就会耗尽,考虑<代码> DOCYList=列表(Cudio.find({}));<代码>其中没有结果