Как я могу получить сумму сумм, используя агрегацию MongoDB?

#mongodb #aggregation-framework

#mongodb #агрегация-фреймворк

Вопрос:

Я хотел бы получить общее (sum) totalHoursForYear значение. Вот моя текущая агрегация:

 const byYear = await this.workHistoryModel.aggregate([
  {
    $group: {
      _id: '$year',
      history: {
        $push: '$ROOT'
      },
      totalHoursForYear: {
        $sum: {
          $add: [
            { $multiply: ['$eightHourDays', 8] },
            { $multiply: ['$tenHourDays', 10] },
            { $multiply: ['$twelveHourDays', 12] },
          ]
        }
      },
    }
  },
]);
 

Теперь мне нужно получить сумму totalHoursForYear , чтобы получить общее количество за все годы. Возможно ли это? Кажется, я не могу правильно понять синтаксис. Когда я пытаюсь добавить другую сумму:

 $group: {
  ...,
  totalHours: {
    $sum: {
      $add: '$totalHoursForYear'
    },
    $push: '$ROOT'
  }
}
 

Я получаю сообщение об ошибке: «В поле «TotalHours» должен быть указан один накопитель»

Комментарии:

1. Я думаю $sum: "$totalHoursForYear" , должно сработать. Удалить $add .

2. Я получаю ту же ошибку: The field 'totalHours' must specify one accumulator

3. Вы добавляете поле TotalHours на том же $group этапе? или не могли бы вы показать конвейер с TotalHours ?

4. он работает нормально mongoplayground.net/p/k9tfvj8mFtJ

5. @styvane Да, я добавляю totalHours на $group этапе

Ответ №1:

Когда вам нужна общая сумма, вы можете сделать другое $group , _id:null что означает рассмотрение всех документов

С помощью вашего скрипта добавьте следующее, чтобы получить итоговую сумму и получить ту же структуру.

 {
    $group: {
      _id: null,
      data: {
        $push: "$ROOT"
      },
      total: {
        $sum: "$totalHoursForYear"
      }
    }
  },
  {
    "$unwind": "$data"
  },
  {
    "$addFields": {
      _id: "$data._id",
      history: "$data.history",
      totalHoursForYear: "$data.totalHoursForYear",
      _id: "$REMOVE",
      data: "$REMOVE"
    }
  }
 

Рабочая игровая площадка Mongo

Комментарии:

1. Спасибо @varman, это работает. Я искренне ценю вашу помощь!

2. @Brandon u r добро пожаловать. есть несколько способов сделать это, попробуйте использовать $facet для практики

3. Интересно. Обычно я работаю с пользовательским интерфейсом, но конвейер агрегации действительно мощный, если вы знаете, как комбинировать операторы и получать доступ к значениям.

4. У @Brandon Compass есть конструктор конвейеров агрегации , который может помочь вам в следующий раз.

5. @HanielBaez Спасибо. Я должен это проверить.