Суммарная сумма MongoDB с поиском в другой коллекции

Есть 2 схемы. Один из них — CostCode, а другой — Timesheet. Каждое расписание связано с одним или несколькими кодами затрат. В расписании есть массив costCodes, и каждый элемент в этом массиве содержит ссылку на CostCode и hoursWorked. Желаемый результат — получить список всех документов CostCode, где каждый документ включает сумму отработанных часов из табелей учета рабочего времени.

Схема CostCode:

{
  label: { type: String, required: false },
  description: { type: String }
  budgetedHours: { type: Number, required: false },
}

Схема расписания:

costCodes: [{
  costCode: { type: Schema.ObjectId, ref: 'CostCode' },
  percentage: { type: Number },
  hoursWorked: { type: Number },
}],
startDateTimeUTC: { type: Date, required: true },
endDateTimeUTC: { type: Date },

Желаемый результат:

{
  _id: "6447dedc26faeedd35b62c0c"
  label: "Cost Code 1"
  description: ""
  budgetedHours: 100
  totalHoursWorked: 53
},
{
  _id: "6445e11b27d9bbb7779bb89b"
  label: "Cost Code 2"
  description: ""
  budgetedHours: 150
  totalHoursWorked: 42
}
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
1
0
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

вариант — написать конвейер агрегации для коллекции CostCode.

  1. первый $lookup в коллекции TimeSheet на основе _id CostCode и costCodes.costCode TimeSheet
  2. $unwind дважды, чтобы получить отдельные документы
  3. отфильтровать с помощью $match документы, где _id равно timesheets.costCodes.costCode
  4. Наконец $group и просуммируйте поля timesheets.costCodes.hoursWorked, чтобы получить totalHoursWorked

здесь детская площадка. в верхней части игровой площадки есть раскрывающийся список «Этап», где вы можете просмотреть промежуточные этапы конвейера.

db.costcode.aggregate([
  { $lookup: { from: "timesheet", localField: "_id", foreignField: "costCodes.costCode", as: "timesheets" } },
  { $unwind: "$timesheets" },
  { $unwind: "$timesheets.costCodes" },
  { $match: { $expr: { $eq: [ "$timesheets.costCodes.costCode", "$_id" ] } } },
  { $group: { _id: "$_id", label: { $first: "$label" }, description: { $first: "$description" }, budgetedHours: { $first: "$budgetedHours" }, totalHoursWorked: { $sum: "$timesheets.costCodes.hoursWorked" } } }
])

Ух ты! Это фантастика и объяснено очень ясно. Спасибо, @cmgchess! Не хватает одной вещи: если код затрат не связан ни с каким расписанием, он все равно будет отображаться, но с totalHoursWorked = 0. Я добавил 3-й код затрат в пример с вашей игровой площадкой... как мы можем также отобразить этот неиспользованный код затрат? ? Спасибо! mongoplayground.net/p/Vyu1ohFU7JU

James Eisenlohr 25.04.2023 23:24

Так что в основном я использовал предохранители при расмотке и в матче не удалял, если нет таймшитов

cmgchess 26.04.2023 04:26

после внимательного изучения вашей последней ссылки на mongoplayground общее количество отработанных часов больше не является точным. Для табелей учета рабочего времени, связанных с несколькими кодами затрат, создается впечатление, что они суммируют hoursWorked из всех них. Как мы можем это исправить? Спасибо.

James Eisenlohr 27.04.2023 02:37

@JamesEisenlohr, ты прав! я пропустил, можете проверить mongoplayground.net/p/2VmqmCefmYn или mongoplayground.net/p/maSsei7bFcd

cmgchess 27.04.2023 04:41

это определенно исправило это! Вы были так полезны! Спасибо. :)

James Eisenlohr 27.04.2023 05:34

Другие вопросы по теме