Следвайте заявката за агрегиране по-долу:
db.shifts.aggregate([{
//this get the day of week and converts them into sunday, saturday
$project: {
jobId:1,
hourlyRate:1,
dayOfWeek: { $dayOfWeek: "$from" },
workedHours: {$divide:[{ $subtract: ["$to", "$from"] }, 3600000]},
saturday:{$floor: {$divide:[{ $dayOfWeek: "$from" }, 7]}},
sunday:{$floor: {$divide:[{$abs:{$subtract:[{ $dayOfWeek: "$from" }, 7]}}, 6]}},
}
}, {
//based on the values of sunday and saturday gets the value of weekday
$project: {
jobId:1,
workedHours:1,
hourlyRate:1,
saturday:1,
sunday: 1,
weekday:{$abs: {$add:["$sunday","$saturday", -1]}},
}
}, {
//here calculates the earnings for each job
$group:{
_id:"$jobId",
sundayEarnings:{$sum: {$multiply:["$sunday", "$hourlyRate", "$workedHours"]}},
saturdayEarnings:{$sum: {$multiply:["$saturday", "$hourlyRate", "$workedHours"]}},
weekdayEarnings:{$sum: {$multiply:["$weekday", "$hourlyRate", "$workedHours"]}},
totalEarnings: {$sum:{$multiply:["$hourlyRate", "$workedHours"]}},
totalWorkedHours: {$sum: "$workedHours"}
}
}, {
//and finally calculates the total jobs earnings
$group:{
_id:null,
jobs:{$push:{
jobId: "$_id",
sundayEarnings: "$sundayEarnings",
saturdayEarnings: "$saturdayEarnings",
weekdayEarnings: "$weekdayEarnings",
totalEarnings: "$totalEarnings",
totalWorkedHours: "$totalWorkedHours"
}},
totalJobsEarning: {$sum: "$totalEarnings"}
}
}])
- Първият
$project
агрегирането дава 0 или 1 стойности доsaturday
иsunday
въз основа наdayOfWeek
стойност чрез извършване на няколко аритметични изчисления. - Втори
$project
агрегацията изчисляваweekday
стойност въз основа наsaturday
иsunday
стойности. - Първата
$group
изчислява приходите за всеки ден във всяка работа. - Най-накрая втората
$group
агрегирането изчислява сумата от приходите на всички работни места.
Тест
Това е моят вход:
{
"_id" : ObjectId("5885a1108c2fc432d649647d"),
"from" : ISODate("2017-01-24T06:21:00Z"),
"to" : ISODate("2017-01-24T08:21:00Z"),
"jobId" : ObjectId("586d7d6acfc7e05669d6e2c8"),
"hourlyRate" : 32
}
{
"_id" : ObjectId("5885a1108c2fc432d649647e"),
"from" : ISODate("2017-01-25T06:21:00Z"),
"to" : ISODate("2017-01-25T08:21:00Z"),
"jobId" : ObjectId("586d7d6acfc7e05669d6e2c8"),
"hourlyRate" : 32
}
{
"_id" : ObjectId("5885a1108c2fc432d649647f"),
"from" : ISODate("2017-01-26T06:21:00Z"),
"to" : ISODate("2017-01-26T08:21:00Z"),
"jobId" : ObjectId("586d7d6acfc7e05669d6e2c8"),
"hourlyRate" : 32
}
{
"_id" : ObjectId("58870cfd59dfb6b0c4eadd72"),
"from" : ISODate("2017-01-28T06:21:00Z"),
"to" : ISODate("2017-01-28T08:21:00Z"),
"jobId" : ObjectId("586d7d6acfc7e05669d6e2c8"),
"hourlyRate" : 32
}
{
"_id" : ObjectId("58870dc659dfb6b0c4eadd73"),
"from" : ISODate("2017-01-29T06:21:00Z"),
"to" : ISODate("2017-01-29T08:21:00Z"),
"jobId" : ObjectId("586d7d6acfc7e05669d6e2c8"),
"hourlyRate" : 32
}
Горната заявка за агрегиране дава следния резултат:
{
"_id" : null,
"jobs" : [
{
"jobId" : ObjectId("586d7d6acfc7e05669d6e2c8"),
"sundayEarnings" : 64,
"saturdayEarnings" : 64,
"weekdayEarnings" : 192,
"totalEarnings" : 320,
"totalWorkedHours" : 10
}
],
"totalJobsEarning" : 320
}
В jobs
масив има само една работа, тъй като колекцията от документи на смени се отнася до един и същ jobId
. Можете да опитате това с различен jobId
s и ще ви осигури различни работни места с общи приходи.