Pro agregační rámec MongoDB jsou k dispozici operátoři agregace data. Například $dayOfYear
operátor se používá k získání této hodnoty z data pro použití při seskupování:
db.collection.aggregate([
{ "$group": {
"_id": { "$dayOfYear": "$datetime" },
"total": { "$sum": "$count" }
}}
])
Nebo můžete místo toho použít metodu výpočtu data. Použitím data epochy převedete objekt data na číslo, kde lze použít matematiku:
db.collection.aggregate([
{ "$group": {
"_id": {
"$subtract": [
{ "$subtract": [ "$datetime", new Date("1970-01-01") ] },
{ "$mod": [
{ "$subtract": [ "$datetime", new Date("1970-01-01") ] },
1000 * 60 * 60 * 24
]}
]
},
"total": { "$sum": "$count" }
}}
])
Pokud to, co hledáte, jsou intervaly od aktuálního bodu v čase, pak to, co chcete, je v podstatě matematický přístup k datu a práci v určitých podmínkách pomocí $cond
operátor:
db.collection.aggregate([
{ "$match": {
"datetime": {
"$gte": new Date(new Date().valueOf() - ( 1000 * 60 * 60 * 24 * 365 ))
}
}},
{ "$group": {
"_id": null,
"24hours": {
"$sum": {
"$cond": [
{ "$gt": [
{ "$subtract": [ "$datetime", new Date("1970-01-01") ] },
new Date().valueOf() - ( 1000 * 60 * 60 * 24 )
]},
"$count",
0
]
}
},
"30days": {
"$sum": {
"$cond": [
{ "$gt": [
{ "$subtract": [ "$datetime", new Date("1970-01-01") ] },
new Date().valueOf() - ( 1000 * 60 * 60 * 24 * 30 )
]},
"$count",
0
]
}
},
"OneYear": {
"$sum": {
"$cond": [
{ "$gt": [
{ "$subtract": [ "$datetime", new Date("1970-01-01") ] },
new Date().valueOf() - ( 1000 * 60 * 60 * 24 * 365 )
]},
"$count",
0
]
}
}
}}
])
Je to v podstatě stejný přístup jako v příkladu SQL, kde dotaz podmíněně vyhodnocuje, zda hodnota data spadá do požadovaného rozsahu, a rozhoduje, zda hodnotu k součtu přidat či nikoli.
Jediným přírůstkem je zde další $match
fázi omezit dotaz tak, aby se zabýval pouze těmi položkami, které by mohly být v rozsahu maximálně jednoho roku, který požadujete. Díky tomu je o něco lepší než prezentovaný SQL v tom, že k odfiltrování těchto hodnot lze použít index a nemusíte "hrubou silou" přes neodpovídající data v kolekci.
Vždy je dobré omezit vstup pomocí $match
při použití agregačního kanálu.