Е, не можете просто да се "гримирате". оператори като $mode
не е оператор за агрегиране и единствените неща, които можете да използвате, са тези, които действително съществуват
.
Така че, за да се върне стойността на категорията в рамките на групирания период от време, който се среща най-често, е необходимо първо да се групира всяка от тези стойности и да се върне броят на повторенията. След това можете да подредите тези резултати по този брой и да върнете стойността на категорията, която е записала най-висок брой в рамките на този период:
// 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" }
}}
Така че $group
на дата и категория и запазване на броя на категориите чрез $sum
. След това $sort
така че най-големият "брой" е отгоре за всяка групирана дата. И накрая използвайте $first
когато приложите друга $group
който просто се прилага към самата дата, за да върне тази категория с най-голям брой за всяка дата.
Не се изкушавайте от оператори като $max
тъй като те не работят тук. Ключовата разлика е „обвързаното“ отношение към „запис/документ“, произведен за всяка стойност на категория. Така че това не е максималния "брой", който искате, или максималната стойност на "категория", а стойността на категорията, която "произведе" най-големия брой. Следователно има $sort
необходими тук.
И накрая някои навици, които „трябва“ да прекъснете:
-
Не използвайте данни за екземпляр на дата във формат извън UTC като вход, освен ако наистина не знаете какво правите. Датите винаги ще се преобразуват в UTC, така че поне в тестовите списъци трябва да свикнете да указвате стойността на датата по този начин.
-
Може да изглежда малко по-изчистено по друг начин, но неща като
1000 * 60 * 60
са много по-описателен код за това, което прави от3600000
. Същата стойност, но една форма е показателна за единиците за време с един поглед. -
Съставен
_id
когато има само една стойност също може да обърка проблемите. Така че няма голям смисъл от достъп до_id.dt
ако това беше единствената налична стойност. Когато има повече от едно свойство в_id
тогава е добре. Но единичните стойности трябва просто да бъдат присвоени обратно на_id
сам. Нищо не е спечелено в противен случай и сингълът е съвсем ясен.