首页 > 解决方案 > 如何通过pymongo检查文档是否为空?

问题描述

我试图阻止 pymongo.errors.InvalidOperation: 获取聚合函数的结果后没有要执行的操作。但是,我使用的方式仍然显示 pymongo.errors.InvalidOperation: No operations to execute for db.collection.insert()。我相信结果在开始的情况下不为空。

这是我的代码:

import sys
from pymongo import MongoClient

client = MongoClient()
db = client['movies']

for i in range(1,db.movies.count() + 1):
    res = db.ratings.aggregate([
        {"$match": {"movieID":str(i)}}, 
        {"$group": {"_id": "$movieID", "avg": {"$avg":"$rating"}}}
        ])
    if list(res) != None:
        db.question1.insert(res)

那么如何在MongoDB中检查文档是否为空呢?

标签: pythonmongodbpymongo

解决方案


这里有几件事可能是错误的:一个是很多 pymongo 的函数返回迭代器。例如:

query = db.customers.find({ 'name': 'John' })
# will print the number of Johns
print len(list(query))
# will always print 0, because the query results have already been
# consumed
print len(list(query))

Python 的list函数接受一个迭代器并创建一个包含迭代器返回的所有元素的列表,因此list(query)将创建一个包含查询返回的所有内容的列表。但是,如果我们不将结果存储list(query)在变量中,它们将永远丢失并且无法再次访问;-)

我不确定是否是这种情况aggregate。如果是这样,你打电话的那一刻你list(res)基本上消耗了所有的结果,所以当你打电话时你不能再次访问它们,insert(res)因为它们已经消失了。

另一个问题是list(res)never None。如果没有结果,list(res)那么[]您实际上想简单地检查一下if list(res)if len(list(res)) > 0。将这两个建议放在一起,我们得到:

import sys
from pymongo import MongoClient

client = MongoClient()
db = client['movies']

for i in range(1,db.movies.count() + 1):
    # Convert db.ratings.aggregate directly to a list
    # Now `res` is a simple list, which can be accessed
    # and traversed many times
    res = list(db.ratings.aggregate([
        {"$match": {"movieID":str(i)}}, 
        {"$group": {"_id": "$movieID", "avg": {"$avg":"$rating"}}}
        ]))
    if len(res) > 0:
        db.question1.insert(res)

推荐阅读