Nou, je kunt niet zomaar "make-up". operators als $mode
is geen aggregatie-operator, en de enige dingen die u kunt gebruiken zijn diegene die echt bestaan
.
Dus om de categoriewaarde te retourneren binnen de gegroepeerde tijdsperiode die het meest voorkomt, is het noodzakelijk om eerst te groeperen op elk van die waarden en het aantal voorkomens terug te geven. Vervolgens kunt u deze resultaten op dat aantal sorteren en de categoriewaarde retourneren die het hoogste aantal binnen die periode heeft geregistreerd:
// 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" }
}}
Dus $group
op zowel datum als categorie en behoud de categorietelling via $sum
. Dan moet je $sort
dus de grootste "telling" staat bovenaan voor elke gegroepeerde datum. En gebruik ten slotte $first
wanneer u een andere $group
toepast dat wordt alleen toegepast op de datum zelf, om die categorie met het grootste aantal voor elke datum terug te geven.
Laat u niet verleiden door operators zoals $max
aangezien ze hier niet werken. Het belangrijkste verschil is de "gebonden" relatie met het "record/document" dat voor elke categoriewaarde wordt geproduceerd. Het is dus niet de maximale "telling" die u wilt of de maximale "categorie"-waarde, maar in plaats daarvan de categoriewaarde die de grootste telling "produceerde". Daarom is er een $sort
hier nodig.
Eindelijk een paar gewoonten die je "moet" doorbreken:
-
Gebruik geen datum-instantiegegevens zonder UTC-indeling als invoer, tenzij u echt weet wat u doet. Datums worden altijd geconverteerd naar UTC, dus in testvermeldingen moet u er in ieder geval aan wennen om de datumwaarde op die manier op te geven.
-
De andere kant op ziet het er misschien wat schoner uit, maar dingen als
1000 * 60 * 60
zijn veel meer beschrijvende code van wat het doet dan3600000
. Dezelfde waarde, maar één vorm is in één oogopslag indicatief voor de tijdseenheden. -
Samengestelde
_id
wanneer er slechts één waarde is, kan dit ook voor verwarring zorgen. Het heeft dus weinig zin om toegang te krijgen tot_id.dt
als dat de enige aanwezige waarde was. Wanneer is meer dan een enkele eigenschap binnen_id
dan is het goed. Maar enkele waarden moeten gewoon weer worden toegewezen aan_id
alleen. Niets anders gewonnen, en single is vrij duidelijk.