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({}));<代码>其中没有结果