PyMongo (3.6.1) - db.collection.aggregate (pipe) НЕ РАБОТАЕТ - PullRequest
0 голосов
/ 31 мая 2018

У меня проблемы с PyMongo, я часами гуглял, но не нашел решения.

Я работаю с некоторыми скриптами Python, чтобы попрактиковаться с MongoDb, который работает на моей локальной машине.Я заполнил свой экземпляр mongoDb одной базой данных "moviesDB", которая содержит 3 разные коллекции:

1. Коллекция фильмов , вот пример документа из этого списка:

{'_id': 1,
 'title': 'Toy Story (1995)',
 'genres': ['Adventure', 'Animation', 'Children', 'Comedy', 'Fantasy'], 
 'averageRating': 3.87,
 'numberOfRatings': 247, 
 'tags': [
            {'_id': ObjectId('5b04970b87977f1fec0fb6e9'), 
             'userId': 501, 
             'tag': 'Pixar',
             'timestamp': 1292956344}
          ]
 }

2. Коллекция рейтингов , которая выглядит следующим образом:

    {    '_id':ObjectId('5b04970c87977f1fec0fb923'), 
         'userId': 1, 
         'movieId': 31, 
         'rating': 2.5, 
         'timestamp': 1260759144}

3. Коллекция тегов, которую я здесь не буду использовать, так что это не важно.

Теперь, что я пытаюсь сделать, это: дать пользователю (в данном примере, пользователю 1) найти все жанры фильмов, которые он оценил, и в каждом жанре перечислить все идентификаторы фильмов, относящиеся к этому жанру.Вот мой код:

"""
This query basically retrieves  movieIds, 
so from the result list of several documents like this:
{
    ObjectId('5b04970c87977f1fec0fb923'),
    'userId': 1, 
    'movieId': 31,
    'rating': 2.5,
    'timestamp': 1260759144},
 retrieves only an array of integers, where each number represent a movie 
 that the user 1 rated."""

movies_rated_by_user = list(db.ratings.distinct(movieId, {userId: 1}))

pipeline = [
    {"$match": {"_id ": {"$in": movies_rated_by_user}}},
    {"$unwind": "$genres"},
    {"$group": {"_id": "$genres", "movies": {"$addToSet": "$_id"}}}]

try:
    """HERE IS THE PROBLEM, SINCE db.movies.aggregate() RETURNS NOTHING!
   so the cursor is empty."""
    cursor = db.movies.aggregate(pipeline, cursor={})
except OperationFailure:
    print("Something went Wrong", file=open("operations_log.txt", "a"))
    print(OperationFailure.details, file=open("operations_log.txt", "a"))
    sys.exit(1)


aggregate_genre = []
for c in cursor:
    aggregate_genre.append(c)

print(aggregate_genre)

Дело в том, что агрегатная функция в коллекции фильмов не извлекает НИЧЕГО, хотя это действительно так, поскольку я попробовал этот запрос на MongoShell, и он работал просто отлично.Вот как выглядит запрос оболочки mongoDB:

db.movies.aggregate(
[
    {$match:{_id : {$in: ids}}},
    {$unwind : "$genres"},
    {$group :
        {
            _id : "$genres",
            movies: { $addToSet : "$_id" }}}
]

);

Где переменные 'ids' определены следующим образом, точно так же, как переменная movies_rated_by_user в коде:

ids= db.ratings.distinct("movieId", {userId : 1});

Результат от метода aggregate выглядит следующим образом (это то, что aggregate_genreпеременная в коде должна содержать):

{ "_id" : "Western", "movies" : [ 3671 ] }
{ "_id" : "Crime", "movies" : [ 1953, 1405 ] }
{ "_id" : "Fantasy", "movies" : [ 2968, 2294, 2193, 1339 ] }
{ "_id" : "Comedy", "movies" : [ 3671, 2294, 2968, 2150, 1405 ] }
{ "_id" : "Sci-Fi", "movies" : [ 2455, 2968, 1129, 1371, 2105 ] }
{ "_id" : "Adventure", "movies" : [ 2193, 2150, 1405, 1287, 2105, 2294, 
    2968, 1371, 1129 ] }

Теперь проблема в методе агрегирования, есть ли ошибка в строке конвейера ??

ПОЖАЛУЙСТА, ПОМОГИТЕ !!Спасибо

1 Ответ

0 голосов
/ 31 мая 2018

Я думаю, вам нужно навести курсор на список, прежде чем итерировать его.Надеюсь, это поможет.

cursor = list(db.movies.aggregate(pipeline, cursor={}))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...