Man kan inte bara "sminka sig". operatorer som $mode
är inte en aggregeringsoperatör, och det enda du kan använda är de som faktiskt existerar
.
Så för att returnera kategorivärdet inom den grupperade tidsperiod som förekommer mest, är det nödvändigt att först gruppera vart och ett av dessa värden och returnera antalet förekomster. Sedan kan du beställa dessa resultat efter det antalet och returnera det kategorivärde som registrerade det högsta antalet inom den perioden:
// 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" }
}}
Så $group
på både datum och kategori och behåll kategoriantalet via $sum
. Sedan $sort
så den största "räkningen" är överst för varje grupperat datum. Och använd slutligen $first
när du använder en annan $group
som bara tillämpas på själva datumet, för att returnera den kategorin med det största antalet för varje datum.
Låt dig inte frestas av operatorer som $max
eftersom de inte fungerar här. Den viktigaste skillnaden är den "bundna" relationen till "posten/dokumentet" som produceras för varje kategorivärde. Det är alltså inte det maximala "antal" du vill ha eller det maximala "kategorivärdet", utan istället kategorivärdet som "producerade" det största antalet. Därför finns det en $sort
behövs här.
Äntligen några vanor du "bör" bryta:
-
Använd inte dataförekomster i icke UTC-format som indata om du inte riktigt vet vad du gör. Datum kommer alltid att konverteras till UTC, så åtminstone i testlistor bör du vänja dig vid att ange datumvärdet på det sättet.
-
Det kan se lite renare ut åt andra hållet men saker som
1000 * 60 * 60
är mycket mer beskrivande kod för vad den gör än3600000
. Samma värde, men en form är en indikation på dess tidsenheter på ett ögonblick. -
Sammansättning av
_id
när det bara finns ett enda värde kan också förvirra problem. Så det finns ingen mening med att komma åt_id.dt
om det var det enda värdet som fanns. När är mer än en enskild egenskap inom_id
då är det bra. Men enstaka värden bör bara tilldelas direkt tillbaka till_id
ensam. Inget vunnit annars, och singel är ganska tydlig.