Има оператори за агрегиране на дати, достъпни за рамката за агрегиране на 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, където заявката условно оценява дали стойността на датата попада в необходимия диапазон и решава дали да добави стойността към сумата или не.
Единственото допълнение тук е допълнителният $match
етап, за да ограничите заявката да действа само върху онези елементи, които евентуално биха били в рамките на максималния диапазон от една година, който искате. Това го прави малко по-добър от представения SQL, тъй като може да се използва индекс за филтриране на тези стойности и не е нужно да „груба сила“ чрез несъответстващи данни в колекцията.
Винаги е добра идея да ограничите въвеждането с $match
когато използвате конвейер за агрегиране.