Existem operadores de agregação de data disponíveis para a estrutura de agregação do MongoDB. Por exemplo, um
$dayOfYear
operador é usado para obter esse valor a partir da data para uso no agrupamento:db.collection.aggregate([
{ "$group": {
"_id": { "$dayOfYear": "$datetime" },
"total": { "$sum": "$count" }
}}
])
Ou você pode usar uma abordagem matemática de datas. Ao aplicar a data de época, você converte o objeto de data em um número onde a matemática pode ser aplicada:
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" }
}}
])
Se o que você procura são intervalos de um ponto no tempo atual, o que você deseja é basicamente a abordagem matemática de datas e trabalhar em algumas condicionais por meio do
$cond
operador: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
]
}
}
}}
])
É essencialmente a mesma abordagem do exemplo SQL, em que a consulta avalia condicionalmente se o valor de data está dentro do intervalo necessário e decide se deve ou não adicionar o valor à soma.
A única adição aqui é o
$match
adicional estágio para restringir a consulta para atuar apenas nos itens que possivelmente estariam dentro do intervalo máximo de um ano que você está solicitando. Isso o torna um pouco melhor do que o SQL apresentado, pois um índice pode ser usado para filtrar esses valores e você não precisa "forçar bruta" por meio de dados não correspondentes na coleção. Sempre é uma boa ideia restringir a entrada com
$match
ao usar um pipeline de agregação.