Python 如何检查pymongo游标是否有查询结果
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26549787/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to check if a pymongo cursor has query results
提问by boh717
I need to check if a findstatement returns a non-empty query.
我需要检查find语句是否返回非空查询。
What I was doing was the following:
我正在做的是以下内容:
query = collection.find({"string": field})
if not query: #do something
Then I realized that my ifstatement was never executed because findreturns a cursor, either the query is empty or not.
然后我意识到我的if语句从未执行过,因为find返回了一个游标,无论查询是否为空。
Therefore I checked the documentationand I find two methods that can help me:
因此,我查看了文档,找到了两种可以帮助我的方法:
count(with_limit_and_skip=False)which (from the description):Returns the number of documents in the results set for this query.
It seems a good way to check, but this means that I need to count all the results in cursor to know if it is zero or not, right? A little bit expensive?
retrievedwhich (from the description):The number of documents retrieved so far.
I tested it on an empty query set and it returns zero, but it's not clear what it does and I don't know if it's right for me.
count(with_limit_and_skip=False)其中(来自描述):返回此查询的结果集中的文档数。
这似乎是一个很好的检查方法,但这意味着我需要计算游标中的所有结果才能知道它是否为零,对吗?有点贵?
retrieved其中(来自描述):到目前为止检索到的文档数。
我在一个空的查询集上测试了它,它返回零,但不清楚它的作用,我不知道它是否适合我。
So, which is the best way (best practice) to check if a find()query returns an empty set or not? Is one of the methods described above right for this purpose? And what about performance? Are there other ways to do it?
那么,检查查询是否find()返回空集的最佳方法(最佳实践)是什么?上面描述的方法之一是否适合此目的?那么性能呢?还有其他方法可以做到吗?
Just to be clear: I need to know if the query is empty and I'd like to find the best way with the cursor with respect to performance and being pythonic.
需要明确的是:我需要知道查询是否为空,并且我想找到关于性能和 Pythonic 的游标的最佳方式。
采纳答案by VooDooNOFX
EDIT: While this was true in 2014, modern versions of pymongo and MongoDB have changed this behaviour. Buyer beware:
编辑:虽然 2014 年确实如此,但现代版本的 pymongo 和 MongoDB 已经改变了这种行为。买家注意:
.count()is the correct way to find the number of results that are returned in the query. The count()method does not exhaust the iterator for your cursor, so you can safely do a .count()check before iterating over the items in the result set.
.count()是查找查询中返回的结果数的正确方法。该count()方法不会耗尽游标的迭代器,因此您可以.count()在迭代结果集中的项目之前安全地进行检查。
Performance of the count method was greatly improved in MongoDB 2.4. The only thing that could slow down your countis if the query has an index set on it, or not. To find out if you have an index on the query, you can do something like
在 MongoDB 2.4 中,count 方法的性能得到了极大的提高。唯一可能会减慢您的速度的count是查询是否设置了索引。要了解查询中是否有索引,您可以执行以下操作
query = collection.find({"string": field})
print query.explain()
If you see BasicCursorin the result, you need an index on your stringfield for this query.
如果您BasicCursor在结果中看到,您需要在您的string字段上为该查询建立索引。
EDIT: as @alvapan pointed out, pymongo deprecated thismethod in pymongo 3.7+ and now prefers you to use count_documentsin a separate query.
编辑:正如@alvapan 所指出的,pymongo在 pymongo 3.7+ 中弃用了此方法,现在更喜欢您count_documents在单独的查询中使用。
item_count = collection.count_documents({"string": field})
The right way to count the number of items you've returned on a query is to check the .retreivedcounter on the query after you iterate over it, or to enumeratethe query in the first place:
计算您在查询中返回的项目数的正确方法是.retreived在迭代后检查查询上的计数器,或者首先enumerate检查查询:
# Using .retrieved
query = collection.find({"string": field})
for item in query:
print(item)
print('Located {0:,} item(s)'.format(query.retrieved))
Or, another way:
或者,另一种方式:
# 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))
回答by Baruch Oxman
How about just using find_oneinstead of find? Then you can just check whether you got a result or None. And if "string" is indexed, you can pass fields = {"string":1, "_id" :0}, and thus make it an index-only query, which is even faster.
只使用find_one而不是怎么样find?然后你可以检查你是否得到了结果或None. 如果“字符串”被索引,您可以传递fields = {"string":1, "_id" :0},从而使其成为仅索引查询,这甚至更快。
回答by Arnaud Fouchet
From my tests, the quickest way is
从我的测试来看,最快的方法是
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
(Using MongoDB 2.6.7, 2015-03-26)
(使用 MongoDB 2.6.7,2015-03-26)
回答by Biplab Malakar
Another solution is converting cursor to list, if the cursor doesn't have any data then empty list else list contains all data.
另一种解决方案是将游标转换为列表,如果游标没有任何数据,则空列表否则列表包含所有数据。
doc_list = collection.find({}); #find all data
have_list = True if len(list(doc_list)) else False;

