Eh bien, vous ne pouvez pas simplement vous "maquiller". opérateurs comme $mode
n'est pas un opérateur d'agrégation, et les seules choses que vous pouvez utiliser sont ceux qui existent réellement
.
Ainsi, afin de renvoyer la valeur de catégorie dans la période de temps groupée qui se produit le plus, il est nécessaire de grouper d'abord sur chacune de ces valeurs et de renvoyer le nombre d'occurrences. Ensuite, vous pouvez trier ces résultats en fonction de ce nombre et renvoyer la valeur de catégorie qui a enregistré le nombre le plus élevé au cours de cette période :
// 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" }
}}
Donc $group
sur la date et la catégorie et conserver le nombre de catégories via $sum
. Ensuite, vous $sort
donc le plus grand "compte" est en haut pour chaque date groupée. Et enfin, utilisez $first
lorsque vous appliquez un autre $group
qui est juste appliqué à la date elle-même, afin de renvoyer cette catégorie avec le plus grand nombre pour chaque date.
Ne vous laissez pas tenter par des opérateurs comme $max
car ils ne travaillent pas ici. La principale différence est la relation "liée" au "record/document" produit pour chaque valeur de catégorie. Ce n'est donc pas le "nombre" maximal que vous voulez ou la valeur maximale de la "catégorie", mais plutôt la valeur de la catégorie qui "a produit" le plus grand nombre. Il existe donc un $sort
nécessaire ici.
Enfin quelques habitudes que vous "devriez" casser :
-
N'utilisez pas de données d'instance de date au format non UTC comme entrée, sauf si vous savez vraiment ce que vous faites. Les dates seront toujours converties en UTC, donc au moins dans les listes de test, vous devriez vous habituer à spécifier la valeur de date de cette façon.
-
Cela peut sembler un peu plus propre dans l'autre sens, mais des choses comme
1000 * 60 * 60
sont un code beaucoup plus descriptif de ce qu'il fait que3600000
. Même valeur, mais un formulaire indique ses unités de temps en un coup d'œil. -
Composé
_id
lorsqu'il n'y a qu'une seule valeur peut également confondre les problèmes. Il est donc inutile d'accéder à_id.dt
si c'était la seule valeur présente. Quand y a-t-il plus d'une seule propriété dans_id
alors c'est bon. Mais les valeurs uniques doivent simplement être attribuées directement à_id
seul. Rien de gagné autrement, et le single est assez clair.