Есть 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
}



вариант — написать конвейер агрегации для коллекции CostCode.
$lookup в коллекции TimeSheet на основе _id CostCode и costCodes.costCode TimeSheet$unwind дважды, чтобы получить отдельные документы$match документы, где _id равно timesheets.costCodes.costCode$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" } } }
])
Так что в основном я использовал предохранители при расмотке и в матче не удалял, если нет таймшитов
после внимательного изучения вашей последней ссылки на mongoplayground общее количество отработанных часов больше не является точным. Для табелей учета рабочего времени, связанных с несколькими кодами затрат, создается впечатление, что они суммируют hoursWorked из всех них. Как мы можем это исправить? Спасибо.
@JamesEisenlohr, ты прав! я пропустил, можете проверить mongoplayground.net/p/2VmqmCefmYn или mongoplayground.net/p/maSsei7bFcd
это определенно исправило это! Вы были так полезны! Спасибо. :)
Ух ты! Это фантастика и объяснено очень ясно. Спасибо, @cmgchess! Не хватает одной вещи: если код затрат не связан ни с каким расписанием, он все равно будет отображаться, но с totalHoursWorked = 0. Я добавил 3-й код затрат в пример с вашей игровой площадкой... как мы можем также отобразить этот неиспользованный код затрат? ? Спасибо! mongoplayground.net/p/Vyu1ohFU7JU