Есть date aggregation operators, доступный для структуры агрегации MongoDB. Так, например, $dayOfYear
оператор используется, чтобы получить это значение с момента для использования в группировке:
db.collection.aggregate([
{ "$group": {
"_id": { "$dayOfYear": "$datetime" },
"total": { "$sum": "$count" }
}}
])
Или вы можете использовать вместо даты математики подход. Применяя дату эпохальных вы преобразовать объект даты в номер, где может быть применена по математике:
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" }
}}
])
Если то, что вы после этих интервалы от текущего момента времени то, что вы хотите в основном дата математика подход и работает в некоторых условных через $cond
оператора:
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
]
}
}
}}
])
Это по сути тот же подход, как пример SQL, где запрос условно оценивает, попадет ли значение даты в требуемом диапазоне и решает, следует ли добавьте v в сумме.
Одно дополнение здесь - дополнительный этап $match
, чтобы ограничить запрос действиями только на те элементы, которые, возможно, будут находиться в пределах максимального диапазона в течение одного года, о котором вы просите. Это делает его немного лучше, чем представленный SQL, поскольку индекс может использоваться для фильтрации этих значений, и вам не нужно «перебирать силу» через несовпадающие данные в коллекции.
Всегда рекомендуется ограничивать ввод $match
при использовании конвейера агрегации.
Мне не нужны суммы каждый день. Мне нужны суммы только этих трех временных интервалов. – jonasasx
@jonasasx Тогда что, по-вашему, вы делаете? Что вы ожидаете?Все суммы в одном результате запроса или выполняются отдельные запросы в порядке? Вы должны объяснить, что вы ожидаете в результате. –
Я хочу получить три записи за каждый интервал (день, неделя, месяц). В идеале, в одном запросе. – jonasasx