У меня проблемы с 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 ] }
Теперь проблема в методе агрегирования, есть ли ошибка в строке конвейера ??
ПОЖАЛУЙСТА, ПОМОГИТЕ !!Спасибо