Bem, você não pode simplesmente "fazer as pazes". operadores como
$mode
não é um operador de agregação, e as únicas coisas que você pode usar são aquelas que realmente existe
. Portanto, para retornar o valor da categoria dentro do período de tempo agrupado que mais ocorre, é necessário agrupar primeiro em cada um desses valores e retornar a contagem de ocorrências. Em seguida, você pode ordenar esses resultados por essa contagem e retornar o valor da categoria que registrou a contagem mais alta nesse período:
// 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" }
}}
Então
$group
na data e na categoria e mantenha a contagem de categorias por meio de $sum
. Então você $sort
portanto, a maior "contagem" está no topo de cada data agrupada. E, finalmente, use $first
quando você aplica outro $group
que é aplicado apenas à própria data, para retornar aquela categoria com a maior contagem para cada data. Não seja tentado por operadores como
$max
pois não funcionam aqui. A principal diferença é a relação "vinculada" ao "registro/documento" produzido para cada valor de categoria. Portanto, não é a "contagem" máxima que você deseja ou o valor máximo da "categoria", mas sim o valor da categoria que "produziu" a maior contagem. Portanto, existe um $sort
preciso aqui. Finalmente alguns hábitos que você “deveria” quebrar:
-
Não use dados de instância de data de formato não UTC como entrada, a menos que você realmente saiba o que está fazendo. As datas sempre serão convertidas para UTC, portanto, pelo menos nas listagens de teste, você deve se acostumar a especificar o valor da data dessa maneira.
-
Pode parecer um pouco mais limpo do outro lado, mas coisas como1000 * 60 * 60
são um código muito mais descritivo do que está fazendo do que3600000
. Mesmo valor, mas uma forma é indicativa de suas unidades de tempo de relance.
-
Compondo_id
quando há apenas um único valor também pode confundir problemas. Portanto, há pouco sentido em acessar_id.dt
se esse fosse o único valor presente. Quando há mais de uma única propriedade dentro de_id
então está bem. Mas valores únicos devem ser atribuídos de volta a_id
sozinho. Nada ganhou de outra forma, e single é bastante claro.