sql >> Databáze >  >> NoSQL >> MongoDB

Seskupit podle více sloupců v MongoDB

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"}
    }
}])
  1. První $project agregace dává buď 0 nebo 1 hodnoty do saturday a sunday na základě dayOfWeek hodnotu provedením několika aritmetických výpočtů.
  2. Druhý $project agregace vypočítá weekday hodnotu podle saturday a sunday hodnoty.
  3. První $group vypočítá výdělky za každý den v každém zaměstnání.
  4. 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.



  1. Dotaz a vložení pomocí jediného příkazu

  2. Je to bezpečný způsob vkládání a aktualizace pole objektů v mongodb?

  3. Převeďte existující atribut řetězce MongoDB na BSON::ObjectId

  4. Jak používat šifrování k ochraně dat MongoDB