MongoDB - Agrégation Cadre (Nombre Total)
Lors de l'exécution normale de "trouver" la requête sur MongoDB je peux obtenir le résultat total count (indépendamment de la limite) par l'exécution de "compter" sur le retour du curseur. Donc, même si je me limite à l'ensemble des résultats à 10 (par exemple) je peux encore savoir que le nombre total de résultats était de 53 ans (encore une fois, par exemple).
Si je comprends bien, l'agrégation cadre, cependant, ne doit pas retourner un curseur, mais simplement les résultats. Et donc, si j'ai utilisé le $limit
opérateur de pipeline, comment puis-je connaître le nombre total de résultats, indépendamment de ladite limite?
Je suppose que je pourrais exécuter l'agrégation de deux fois (une fois pour compter les résultats via $group
, et une fois avec $limit
pour le nombre de résultats), mais cela semble inefficace.
Une approche alternative pourrait être de fixer le nombre total de résultats pour les documents (via $group
) avant la $limit
opération, mais cela semble aussi inefficace que ce nombre sera joint à chaque document (au lieu de simplement retourné une seule fois pour l'ensemble).
Suis-je manqué quelque chose? Des idées? Merci!
Par exemple, si c'est la requête:
db.article.aggregate(
{ $group : {
_id : "$author",
posts : { $sum : 1 }
}},
{ $sort : { posts: -1 } },
{ $limit : 5 }
);
Comment puis-je savoir combien de résultats sont disponibles (avant $limit
)? Le résultat n'est pas un curseur, donc je ne peux pas il suffit d'exécuter compter sur elle.
Ajout d'un exemple de code. La question, cependant, est générique (je pense). Merci!
OriginalL'auteur Assaf Hershko | 2013-07-20
Vous devez vous connecter pour publier un commentaire.
Assaf, il va y avoir quelques améliorations à l'agrégation de cadre dans un avenir proche qui peut vous permettre de faire vos calculs en une seule passe facilement, mais pour l'instant, il est préférable d'effectuer vos calculs par l'exécution de deux requêtes en parallèle: l'un pour agréger les #postes pour vos meilleurs auteurs, et une autre agrégation pour calculer le total des postes pour tous les auteurs. Notez également que si tout ce que vous devez faire est de compter sur les documents, à l'aide de la fonction de comptage est un moyen très efficace d'effectuer le calcul. MongoDB caches compte dans btree indices permettant très rapide compte sur les requêtes.
Si ces agrégations à son tour d'être lent, il ya un couple de stratégies. Tout d'abord, gardez à l'esprit que vous souhaitez démarrer la requête $avec un match le cas échéant, pour réduire le jeu de résultats. $matches peuvent également être accélérer les index. Deuxièmement, vous pouvez effectuer ces calculs de pré-agrégations. Au lieu d'possible l'exécution de ces agrégations chaque fois qu'un utilisateur accède à une certaine partie de votre application, ont les agrégations exécuter régulièrement en arrière-plan et de stocker les agrégations dans une collection qui contient des valeurs pré-agrégées. De cette façon, vos pages peut simplement interroger les valeurs pré calculées à partir de cette collection.
savez-vous si ces améliorations ont encore été terminé?
OriginalL'auteur Dylan Tong
Il y a une solution à l'aide de push et de tranche: https://stackoverflow.com/a/39784851/4752635 (@emaniacs en parle très bien ici).
Mais je préfère utiliser 2 requêtes. Solution poussant $$ROOT et de l'utilisation de $tranche s'exécute dans le document limitation de la mémoire de 16 MO pour de grandes collections. Aussi, pour les grandes collections de deux requêtes semblent courir plus vite que celui de $$RACINE de pousser. Vous pouvez les exécuter en parallèle, de sorte que vous ne sont limitées que par le plus lent des deux requêtes (probablement celui qui trie).
J'ai réglé avec cette solution à l'aide de 2 requêtes de l'agrégation et de cadre (note - je utiliser node.js dans cet exemple):
OriginalL'auteur Filip Voska
- Je obtenir comptage total avec
aggregate().toArray().length
OriginalL'auteur user9337014
Si vous ne voulez pas exécuter deux requêtes en parallèle (un pour agréger les #postes pour vos meilleurs auteurs, et une autre agrégation pour calculer le total des postes pour tous les auteurs), vous pouvez simplement supprimer $limite sur le pipeline et sur les résultats, vous pouvez utiliser
ex:
OriginalL'auteur Công Thắng
dans mon cas, nous utilisons $de la phase de vidage de aggeration dans un temp/cache de la table, puis de compter. et, puisque nous avons besoin de trier et de paginer les résultats, nous avons ajouter un index sur la table temp et enregistrer le nom de la table dans la session, retirez le tableau de la session de clôture/délai d'expiration du cache.
OriginalL'auteur butfly
J'ai eu le même problème, résolu avec $projet, $tranche et $$ROOT.
Vous devez déclarer
from
etto
variable.https://docs.mongodb.com/manual/reference/operator/aggregation/slice/
OriginalL'auteur emaniacs
$facettes opération d'agrégation peut être utilisé pour Mongo versions >= 3.4.
Cela permet à la fourchette à une étape particulière d'un pipeline dans plusieurs sous-pipelines permettant dans ce cas de construire un pipeline sous pour compter le nombre de documents et un autre pour trier, sauter, limitation de.
Cela permet d'éviter de faire les mêmes étapes à plusieurs reprises dans de multiples demandes.
OriginalL'auteur Hugo LEFEBVRE