È necessario determinare in modo condizionale la chiave di raggruppamento in base al punto in cui la data corrente rientra nell'intervallo. Ciò si ottiene fondamentalmente tramite $cond
con condizioni nidificate e la variante logica di $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" }
}}
])
Come $cond
è un operatore ternario, la prima condizione viene valutata per vedere se la condizione è vera, e quando true viene restituito il secondo argomento, altrimenti viene restituito il terzo quando false. Quindi annidando un altro $cond
nel caso falso ottieni il test logico su dove cade la data, o "meno della data di 15 giorni" che significa che è nell'intervallo più vecchio, o "meno di 7 giorni" che significa l'intervallo medio, o ovviamente è in la gamma più recente.
Sto solo anteponendo i numeri qui meno di 10 con uno 0
quindi ti dà qualcosa da ordinare se vuoi, poiché l'output di "chiavi" in $group
non è di per sé ordinato.
Ma è così che lo fai in una singola query. Devi solo capire quale dovrebbe essere la chiave di raggruppamento in base a dove cade la data e accumulare per ogni chiave.