Du skal betinget bestemme grupperingsnøglen baseret på, hvor den aktuelle dato falder mellem intervallet. Dette opnås grundlæggende via $cond
med indlejrede betingelser og den logiske variant af $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" }
}}
])
Som $cond
er en ternær operator, evalueres den første betingelse for at se, om betingelsen er sand, og når den er sand, returneres det andet argument ellers returneres den tredje, når den er falsk. Så ved at indlejre endnu en $cond
i det falske tilfælde får du den logiske test på, hvor datoen falder, enten "mindre end 15 dages dato", hvilket betyder, at den er i det ældste interval, eller "mindre end 7 dage", som betyder mellemområdet, eller selvfølgelig er det i den nyeste serie.
Jeg sætter bare tallene her mindre end 10 foran med en 0
så det giver dig noget at sortere på, hvis du vil, da outputtet af "nøgler" i $group
er ikke i sig selv bestilt.
Men det er sådan, du gør det i en enkelt forespørgsel. Du regner bare ud, hvad grupperingsnøglen skal være baseret på, hvor datoen falder, og akkumulerer for hver nøgle.