Как проверить, пуст ли документ по pymongo? - PullRequest
0 голосов
/ 01 октября 2018

Я пытался предотвратить pymongo.errors.InvalidOperation: Нет операций, которые нужно выполнить после получения результата агрегатной функции.Однако способ, который я использовал, по-прежнему показывает pymongo.errors.InvalidOperation: Нет операций, которые нужно выполнить для 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?

1 Ответ

0 голосов
/ 02 октября 2018

Здесь есть пара вещей, которые могут быть неправильными: одна из них состоит в том, что многие функции 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) никогда не будет 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)
...