Postupujte podle níže uvedeného agregačního dotazu:
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"}
}
}])
- První
$project
agregace dává buď 0 nebo 1 hodnoty dosaturday
asunday
na základědayOfWeek
hodnotu provedením několika aritmetických výpočtů. - Druhý
$project
agregace vypočítáweekday
hodnotu podlesaturday
asunday
hodnoty. - První
$group
vypočítá výdělky za každý den v každém zaměstnání. - Konečně druhá
$group
agregace vypočítá součet výdělků všech zaměstnání.
Test
Toto je můj příspěvek:
{
"_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
}
Výše uvedený agregační dotaz poskytuje následující výstup:
{
"_id" : null,
"jobs" : [
{
"jobId" : ObjectId("586d7d6acfc7e05669d6e2c8"),
"sundayEarnings" : 64,
"saturdayEarnings" : 64,
"weekdayEarnings" : 192,
"totalEarnings" : 320,
"totalWorkedHours" : 10
}
],
"totalJobsEarning" : 320
}
V jobs
pole existuje pouze jedna úloha, protože kolekce dokumentů směny odkazuje na stejné jobId
. Můžete to zkusit s jiným jobId
s a dá vám různé práce s celkovými výdělky.