#mongodb #aggregation-framework
Вопрос:
У меня есть две коллекции MongoDB:
фильм
{ _id: ObjectId("60644a81655e8216acf44b6e"), name: 'Django' }
{ _id: ObjectId("60647242c31ba840a0479221"), name: 'Kill Bill' }
скрининг
{ _id: ObjectId("60644598655e8216acf44b6a"),
name: 'Django',
reviews: '1150',
cinema: '01' }
{ _id: ObjectId("606445c7655e8216acf44b6b"),
name: 'Django',
reviews: '2130',
cinema: '02' }
{ _id: ObjectId("606445c7655e8216acf44b6c"),
name: 'Django',
reviews: '2102',
cinema: '03' }
{ _id: ObjectId("60647218c31ba840a047921f"),
name: 'Kill Bill',
reviews: '2000',
cinema: '01' }
{ _id: ObjectId("60647218c31ba840a0479220"),
name: 'Kill Bill',
reviews: '587',
cinema: '02' }
Я хочу добавить в коллекцию ФИЛЬМОВ новое поле агрегации total_reviews, которое суммирует общее количество просмотров ФИЛЬМА; например:
фильм
{ _id: ObjectId("60644a81655e8216acf44b6e"), name: 'Django', total_reviews: "3382" }
{ _id: ObjectId("60647242c31ba840a0479221"), name: 'Kill Bill', total_reviews: "2587"}
Кто-нибудь, я могу мне помочь?
Спасибо…
Комментарии:
1. MongoDB является базой данных документов и как таковой не поддерживает вычисляемые поля. Вы можете, как вы уже продемонстрировали, использовать структуру агрегирования для получения «вычисленных» результатов в виде курсора или в виде новой коллекции.
Ответ №1:
Я изменил пункт on при слиянии, и это работает
db.film.aggregate([
{$lookup: {from: "screening", localField: "_id", foreignField: "film_id", as: "screening"}},
{$set: {total_reviews : {$sum : "$screening.review"}}},
{$project : {id:0, screening:0}},
{ $merge: { into: { db: "test", coll: "film" }, on: "_id", whenMatched: "replace", whenNotMatched: "insert" } }
])
Но если вставить новый документ проверки, поле total_reviews не обновляется автоматически. Существует метод (например, триггер SQL) для автоматизации этой функции?
Комментарии:
1. Если это исправление к ответу, отредактируйте ответ, это не два ответа, если только они не являются двумя существенно различными решениями, которые оба работают, и даже в этом случае они должны быть указаны в качестве вариантов в одном ответе.
Ответ №2:
Это правильное решение, которое предусматривает 4 этапа:
db.film.aggregate([
{$lookup: {from: "screening", localField: "name", foreignField: "name", as: "screening"}},
{$addFields: {total_reviews : {$sum : "$screening.review"}}},
{$project : {id:0, screening:0}},
{$merge: {into: {db: "test", coll: "film"}, on: "_id",
whenMatched: "replace",whenNotMatched: "insert"}}
])
И это результат:
[{ name: 'Django', total_reviews: 5382 },
{ name: 'Kill Bill', total_reviews: 2587 }]