Musisz warunkowo określić klucz grupowania na podstawie tego, gdzie bieżąca data przypada między zakresem. Zasadniczo osiąga się to poprzez $cond
z zagnieżdżonymi warunkami i logicznym wariantem $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" }
}}
])
Jako $cond
jest operatorem trójargumentowym, pierwszy warunek jest oceniany, aby sprawdzić, czy warunek jest prawdziwy, a gdy jest prawdziwy, zwracany jest drugi argument, w przeciwnym razie zwracany jest trzeci, gdy jest fałszem. Więc zagnieżdżając inny $cond
w fałszywym przypadku otrzymujesz test logiczny na miejsce, w którym przypada data, albo „mniej niż 15-dniowa data”, co oznacza, że jest w najstarszym zakresie, lub „mniej niż 7 dni”, co oznacza środkowy zakres, lub oczywiście jest w najnowszy asortyment.
Po prostu poprzedzam liczby mniejsze niż 10 przedrostkiem 0
więc daje ci coś do sortowania, jeśli chcesz, ponieważ wyjście "kluczy" w $group
nie jest sam w sobie uporządkowany.
Ale tak to robisz w jednym zapytaniu. Po prostu ustalasz, jaki klucz grupujący powinien opierać się na miejscu, w którym przypada data i akumulować dla każdego klucza.