如何检查pymongo游标是否有查询结果

时间:2014-10-24 14:18:15

标签: python mongodb pymongo mongodb-query

我需要检查find语句是否返回非空查询。

我正在做的是以下内容:

query = collection.find({"string": field})
if not query: #do something

然后我意识到我的if语句从未被执行,因为find返回一个游标,或者查询是否为空。

因此,我检查了documentation,我找到了两种可以帮助我的方法:

  1. count(with_limit_and_skip=False)(来自说明):

      

    返回此查询的结果集中的文档数。

    这似乎是一种检查的好方法,但这意味着我需要数数 光标中的所有结果都知道它是否为零,对吧?有点贵?

  2. retrieved(来自说明):

      

    到目前为止检索的文件数量。

    我在一个空的查询集上测试它并返回零,但事实并非如此 明确它的作用,我不知道它是否适合我。

  3. 那么,检查find()查询是否返回空集的最佳方法(最佳实践)是什么?上面描述的方法之一是否适用于此目的?性能怎么样?还有其他方法吗?


    要明确一点:我需要知道查询是否为空,我想找到关于性能和pythonic的光标的最佳方法。

4 个答案:

答案 0 :(得分:33)

编辑虽然2014年确实如此,现代版本的pymongo和MongoDB已经改变了这种行为。买家要小心:

.count()是查找查询中返回的结果数的正确方法。 count()方法不会耗尽游标的迭代器,因此您可以在迭代结果集中的项之前安全地进行.count()检查。

MongoDB 2.4中计数方法的性能大大提高。唯一可能减慢count速度的因素是查询是否设置了索引。要查明您是否有查询索引,您可以执行类似

的操作
query = collection.find({"string": field})
print query.explain()

如果您在结果中看到BasicCursor,那么您需要在string字段中为此查询添加索引。


编辑:正如@a​​lvapan指出,pymongo 3.7+中的pymongo deprecated this方法,现在更喜欢在单独的查询中使用count_documents

item_count = collection.count_documents({"string": field})

计算您在查询中返回的项目数量的正确方法是在迭代后检查查询上的.retreived计数器,或者在第一个查询中enumerate查询位:

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

答案 1 :(得分:7)

仅使用find_one代替find怎么样?然后,您可以检查是否有结果或None。如果" string"如果已建立索引,则可以传递fields = {"string":1, "_id" :0},从而使其成为仅索引查询,甚至更快。

答案 2 :(得分:5)

另一个解决方案是将光标转换为列表,如果光标没有任何数据,则空列表其他列表包含所有数据。

 doc_list = collection.find({}); #find all data
 have_list = True if len(list(doc_list)) else False;

答案 3 :(得分:3)

从我的测试中,最快的方法是

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.7,2015-03-26)