U moet de groeperingssleutel voorwaardelijk bepalen op basis van waar de huidige datum binnen het bereik valt. Dit wordt in principe bereikt via $cond
met geneste voorwaarden en de logische variant van $lt
:
// work out dates somehow
var today = new Date(),
oneDay = ( 1000 * 60 * 60 * 24 ),
thirtyDays = new Date( today.valueOf() - ( 30 * oneDay ) ),
fifteenDays = new Date( today.valueOf() - ( 15 * oneDay ) ),
sevenDays = new Date( today.valueOf() - ( 7 * oneDay ) );
db.collection.aggregate([
{ "$match": {
"date": { "$gte": thirtyDays }
}},
{ "$group": {
"_id": {
"$cond": [
{ "$lt": [ "$date", fifteenDays ] },
"16-30",
{ "$cond": [
{ "$lt": [ "$date", sevenDays ] },
"08-15",
"01-07"
]}
]
},
"count": { "$sum": 1 },
"totalValue": { "$sum": "$value" }
}}
])
Als $cond
is een ternaire operator, wordt de eerste voorwaarde geëvalueerd om te zien of de voorwaarde waar is, en wanneer waar het tweede argument wordt geretourneerd, anders wordt de derde geretourneerd wanneer onwaar. Dus door een andere $cond
. te nesten in het valse geval krijg je de logische test op waar de datum valt, ofwel "minder dan de 15-dagdatum", wat betekent dat het in het oudste bereik is, of "minder dan 7 dagen", wat het middelste bereik betekent, of natuurlijk is het in het nieuwste assortiment.
Ik voeg de cijfers hier minder dan 10 vooraf met een 0
dus het geeft je iets om op te sorteren als je wilt, aangezien de uitvoer van "sleutels" in $group
is op zichzelf niet besteld.
Maar zo doe je dat in een enkele query. Je zoekt gewoon uit wat de groeperingssleutel moet zijn op basis van waar de datum valt en verzamelt zich voor elke sleutel.