Vâng, bạn không thể chỉ "trang điểm". toán tử dưới dạng $mode
không phải là toán tử tổng hợp và những thứ duy nhất bạn có thể sử dụng là những thứ thực sự tồn tại
.
Vì vậy, để trả về giá trị danh mục trong khoảng thời gian được nhóm xuất hiện nhiều nhất, trước tiên cần phải nhóm trên mỗi giá trị đó và trả về số lần xuất hiện. Sau đó, bạn có thể sắp xếp các kết quả này theo số lượng đó và trả về giá trị danh mục đã ghi lại số lượng cao nhất trong khoảng thời gian đó:
// 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" }
}}
Vì vậy, $group
vào cả ngày và danh mục và giữ lại số lượng danh mục qua $sum
. Sau đó, bạn $sort
vì vậy "số lượng" lớn nhất ở trên cùng cho mỗi ngày được nhóm. Và cuối cùng sử dụng $first
khi bạn áp dụng một $group
khác chỉ được áp dụng cho chính ngày đó, để trả về danh mục đó với số lượng lớn nhất cho mỗi ngày.
Đừng để bị cám dỗ bởi các toán tử như $max
vì họ không làm việc ở đây. Sự khác biệt chính là sự liên kết "gắn liền" với "bản ghi / tài liệu" được tạo cho mỗi giá trị danh mục. Vì vậy, nó không phải là "số lượng" tối đa bạn muốn hoặc giá trị "danh mục" tối đa, mà thay vào đó là giá trị danh mục "tạo ra" số lượng lớn nhất. Do đó có $sort
cần thiết ở đây.
Cuối cùng, một số thói quen bạn "nên" phá bỏ:
-
Không sử dụng dữ liệu phiên bản ngày không định dạng UTC làm đầu vào trừ khi bạn thực sự biết mình đang làm gì. Ngày sẽ luôn được chuyển đổi sang UTC, vì vậy ít nhất trong danh sách thử nghiệm, bạn nên quen với việc chỉ định giá trị ngày theo cách đó.
-
Theo cách khác, nó có thể trông gọn gàng hơn một chút nhưng những thứ như
1000 * 60 * 60
là nhiều mã mô tả rõ ràng hơn về những gì nó đang làm so với3600000
. Cùng một giá trị, nhưng một dạng biểu thị đơn vị thời gian trong nháy mắt. -
Kết hợp
_id
khi chỉ có một giá trị duy nhất cũng có thể gây nhầm lẫn cho các vấn đề. Vì vậy, có rất ít điểm trong việc tích lũy_id.dt
nếu đó là giá trị duy nhất hiện tại. Khi có nhiều thuộc tính trong_id
sau đó nó là tốt. Nhưng các giá trị đơn lẻ chỉ nên được gán lại ngay cho_id
một mình. Không có gì khác được, và độc thân là khá rõ ràng.