Nah Anda tidak bisa hanya "make up". operator sebagai $mode
bukan operator agregasi, dan satu-satunya hal yang dapat Anda gunakan adalah yang sebenarnya ada
.
Jadi untuk mengembalikan nilai kategori dalam periode waktu yang dikelompokkan yang paling banyak terjadi, perlu untuk mengelompokkan terlebih dahulu pada masing-masing nilai tersebut dan mengembalikan hitungan kemunculannya. Kemudian Anda dapat mengurutkan hasil ini dengan hitungan tersebut, dan mengembalikan nilai kategori yang mencatat jumlah tertinggi dalam periode tersebut:
// Filter dates
{ "$match": {
"dt": {
"$gt": new Date("October 13, 2010 12:00:00"),
"$lt": new Date("November 13, 2010 12:00:00")
}
}},
// Group by hour and category, with avg and count
{ "$group": {
"_id": {
"dt": {
"$add": [
{
"$subtract": [
{ "$subtract": ["$dt", new Date(0)] },
{
"$mod": [
{ "$subtract": ["$dt", new Date(0)] },
3600000//1000 * 60 * 60
]
}
]
},
new Date(0)
]
},
"category": "$category"
},
"price": { "$avg": "$price" },
"count": { "$sum": 1 }
}},
// Sort on date and count
{ "$sort": { "_id.dt": 1, "count": -1 }},
// Group on just the date, keeping the avg and the first category
{ "$group": {
"_id": "$_id.dt",
"price": { "$avg": "$price"}
"category": { "$first": "$_id.category" }
}}
Jadi $group
pada tanggal dan kategori dan pertahankan jumlah kategori melalui $sum
. Kemudian Anda $sort
jadi "hitungan" terbesar ada di atas untuk setiap tanggal yang dikelompokkan. Dan terakhir gunakan $first
ketika Anda menerapkan $group
lain yang baru saja diterapkan pada tanggal itu sendiri, untuk mengembalikan kategori tersebut dengan jumlah terbesar untuk setiap tanggal.
Jangan tergiur oleh operator seperti $max
karena mereka tidak bekerja di sini. Perbedaan utama adalah hubungan "terikat" dengan "catatan/dokumen" yang dihasilkan untuk setiap nilai kategori. Jadi bukan maksimim "hitungan" yang Anda inginkan atau nilai "kategori" maksimum, melainkan nilai kategori yang "menghasilkan" hitungan terbesar. Karenanya ada $sort
dibutuhkan di sini.
Akhirnya beberapa kebiasaan yang "harus" Anda hentikan:
-
Jangan gunakan data contoh tanggal format non UTC sebagai input kecuali Anda benar-benar tahu apa yang Anda lakukan. Tanggal akan selalu dikonversi ke UTC, jadi setidaknya dalam daftar pengujian, Anda harus terbiasa menentukan nilai tanggal seperti itu.
-
Mungkin terlihat sedikit lebih bersih dengan cara lain tetapi hal-hal seperti
1000 * 60 * 60
adalah kode yang lebih deskriptif tentang apa yang dilakukannya daripada3600000
. Nilai yang sama, tetapi satu bentuk menunjukkan unit waktunya secara sekilas. -
Menggabungkan
_id
ketika hanya ada satu nilai juga dapat membingungkan masalah. Jadi tidak ada gunanya mengakses_id.dt
jika itu adalah satu-satunya nilai yang ada. Kapan lebih dari satu properti dalam_id
maka itu baik-baik saja. Tetapi nilai tunggal harus ditetapkan kembali ke_id
sendiri. Tidak ada yang diperoleh sebaliknya, dan lajang cukup jelas.