Der er datosammenlægningsoperatører tilgængelige for MongoDBs aggregeringsramme. Så for eksempel en $dayOfYear
operator bruges til at hente denne værdi fra datoen til brug i gruppering:
db.collection.aggregate([
{ "$group": {
"_id": { "$dayOfYear": "$datetime" },
"total": { "$sum": "$count" }
}}
])
Eller du kan bruge en datomatematisk tilgang i stedet for. Ved at anvende epokedatoen konverterer du datoobjektet til et tal, hvor matematikken kan anvendes:
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" }
}}
])
Hvis det, du leder efter, er intervaller fra et aktuelt tidspunkt, så er det, du ønsker, dybest set datomatematisk tilgang og arbejde i nogle betingelser via $cond
operatør:
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
]
}
}
}}
])
Det er i bund og grund den samme tilgang som SQL-eksemplet, hvor forespørgslen betinget evaluerer, om datoværdien falder inden for det påkrævede interval og beslutter, om værdien skal føjes til summen.
Den ene tilføjelse her er den ekstra $match
trin for at begrænse forespørgslen til kun at handle på de elementer, der muligvis ville være inden for det maksimale et-årsinterval, du beder om. Det gør det en smule bedre end den præsenterede SQL, da et indeks kunne bruges til at filtrere disse værdier ud, og du behøver ikke at "brute force" gennem ikke-matchende data i samlingen.
Det er altid en god idé at begrænse inputtet med $match
ved brug af en aggregeringspipeline.