Ada operator agregasi tanggal yang tersedia untuk kerangka agregasi MongoDB. Jadi misalnya $dayOfYear
operator digunakan untuk mendapatkan nilai tersebut dari tanggal untuk digunakan dalam pengelompokan:
db.collection.aggregate([
{ "$group": {
"_id": { "$dayOfYear": "$datetime" },
"total": { "$sum": "$count" }
}}
])
Atau Anda dapat menggunakan pendekatan matematika tanggal sebagai gantinya. Dengan menerapkan tanggal epoch Anda mengonversi objek tanggal menjadi angka di mana matematika dapat diterapkan:
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" }
}}
])
Jika yang Anda cari adalah interval dari titik waktu saat ini, maka yang Anda inginkan pada dasarnya adalah pendekatan matematika tanggal dan bekerja dalam beberapa kondisi melalui $cond
operator:
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
]
}
}
}}
])
Ini pada dasarnya adalah pendekatan yang sama dengan contoh SQL, di mana kueri mengevaluasi secara kondisional apakah nilai tanggal berada dalam rentang yang diperlukan dan memutuskan apakah akan menambahkan nilai ke penjumlahan atau tidak.
Satu tambahan di sini adalah tambahan $match
tahap untuk membatasi kueri agar hanya bertindak pada item-item yang mungkin berada dalam rentang maksimum satu tahun yang Anda minta. Itu membuatnya sedikit lebih baik daripada SQL yang disajikan karena indeks dapat digunakan untuk memfilter nilai-nilai itu dan Anda tidak perlu "memaksa" melalui data yang tidak cocok dalam koleksi.
Sebaiknya batasi masukan dengan $match
saat menggunakan pipeline agregasi.