Поле агрегации в MongoDB

#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 }]