Chapitre 7. Exploration de données via des agrégations

Ce chapitre couvre

  • Agrégations de métriques
  • Agrégations à un ou plusieurs compartiments
  • Agrégations imbriquées
  • Liens entre les requêtes, les filtres et les agrégations

Jusqu’à présent, dans ce livre, nous nous sommes concentrés sur l’indexation et la recherche: vous disposez de nombreux documents et l’utilisateur souhaite trouver les correspondances les plus pertinentes pour certains mots clés. Sauf qu’il y a de plus en plus de cas d’utilisation où les utilisateurs ne sont pas du tout intéressés par des résultats spécifiques. Au lieu de cela, ils veulent obtenir des statistiques à partir d’un ensemble de documents. Ces statistiques peuvent être des sujets d’actualité, des tendances de revenus pour différents produits, le nombre de visiteurs uniques sur votre site Web, etc.

Les agrégations dans Elasticsearch résolvent ce problème en chargeant les documents correspondant à votre recherche et en effectuant toutes sortes de calculs, tels que le décompte des termes d’un champ de type chaine de charactères ou le calcul de la moyenne d’un champ numérique. Pour examiner le fonctionnement des agrégations, nous allons utiliser un exemple tiré du site get-together avec lequel vous avez travaillé dans les chapitres précédents: un utilisateur qui accède à votre site peut ne pas savoir quels groupes rechercher. Pour donner à l’utilisateur un élément de base, vous pouvez faire en sorte que l’interface utilisateur affiche les tags les plus populaires pour les groupes existants de votre site de rencontre, comme illustré à la figure 7.1.

Ces balises seraient stockées dans un champ séparé de vos documents de type « groupe ». L’utilisateur peut alors sélectionner une balise et filtrer uniquement les documents contenant cette balise. Cela permet aux utilisateurs de trouver plus facilement des groupes correspondant à leurs intérêts.

Pour obtenir une telle liste de balises populaires dans Elasticsearch, vous utiliseriez des agrégations. Dans ce cas spécifique, vous utiliseriez l’agrégation de termes sur le champ des balises, qui compte les occurrences de chaque terme dans ce champ et renvoie les termes les plus fréquents. . De nombreux autres types d’agrégations sont également disponibles et nous en discuterons plus tard dans ce chapitre. Par exemple, vous pouvez utiliser une agrégation date_histogram pour afficher le nombre d’événements survenus chaque mois de la dernière année, utiliser l’agrégation avg pour afficher le nombre moyen de participants pour chaque événement ou même rechercher les utilisateurs qui ont le même goût pour les événements. comme vous le faites en utilisant l’agrégation significaant_terms.



Qu’en est-il des facettes?
Si vous utilisez Lucene, Solr ou même Elasticsearch depuis un certain temps, vous avez peut-être entendu parler de facettes. Les facettes ressemblent aux agrégations, car elles chargent également les documents correspondant à votre requête et effectuent des calculs afin de renvoyer des statistiques. Les facettes sont toujours prises en charge dans les versions 1.x mais sont obsolètes et seront supprimées dans la version 2.0.

La principale différence entre les agrégations et les facettes est que vous ne pouvez pas imbriquer plusieurs types de facettes dans Elasticsearch, ce qui limite les possibilités d’exploration de vos données. Par exemple, si vous avez un site de blogging, vous pouvez utiliser la facette  terms pour identifier les sujets d’actualité cette année, ou bien la facette histogram, des dates pour savoir combien d’articles sont publiés chaque jour. Mais vous ne pourriez pas trouver le nombre de messages par jour, séparément pour chaque sujet (au moins pas dans une demande). Pour y arriver il faudrait imbriquer la facette histogram, de la date sous la facette terms.

Des agrégations ont été créées pour supprimer cette limite et vous permettre de mieux comprendre vos documents. Par exemple, si vous stockez les logs de votre solution de e-commerce dans Elasticsearch, vous pouvez utiliser des agrégations pour rechercher non seulement les produits les plus vendus, mais également les produits les plus vendus dans chaque pays, les tendances pour chaque produit dans chaque pays, etc.



Dans ce chapitre, nous aborderons d’abord les caractéristiques communes à toutes les agrégations: leur mode d’exploitation et leur relation avec les query et les filtres définis dans les chapitres précédents. Nous nous pencherons ensuite sur les particularités de chaque type d’agrégation et nous vous montrerons finalement comment combiner différents types d’agrégation.

Les agrégations sont divisées en deux catégories principales: les métriques et les compartiments(buckets). Les agrégations de métriques font référence à l’analyse statistique d’un groupe de documents, donnant lieu à des métriques telles que la valeur minimale, la valeur maximale, l’écart type, etc. Par exemple, vous pouvez obtenir le prix moyen des articles dans une boutique en ligne ou le nombre d’utilisateurs uniques qui s’y connectent.

Les agrégations de compartiments divisent les documents correspondants dans un ou plusieurs conteneurs (compartiments), puis vous indiquent le nombre de documents dans chaque compartiment. L’agrégation terms, qui vous donnerait les balises les plus populaires de la figure 7.1, crée un compartiment de documents pour chaque balise et vous indique le nombre de documents pour chaque compartiment.

Dans une agrégation de compartiment, vous pouvez imbriquer d’autres agrégations, ce qui permet d’exécuter la sous-agrégation sur chaque compartiment de documents générés par l’agrégation de niveau supérieur. Vous pouvez voir un exemple à la figure 7.2.

En regardant la figure de haut en bas, vous pouvez voir que si vous utilisez l’agrégation terms pour obtenir les balises de groupe les plus populaires, vous pouvez également obtenir le nombre moyen de membres pour les groupes correspondant à chaque balise. Vous pouvez également demander à Elasticsearch de vous donner, par balise, le nombre de groupes créés par an.

Comme vous pouvez l’imaginer, vous pouvez combiner de nombreux types d’agrégations de différentes manières. Pour obtenir une meilleure vue des options disponibles, nous allons passer en revue les métriques et les agrégations de compartiments, puis discuter de la façon dont vous pouvez les combiner. Mais voyons d’abord ce qui est commun à tous les types d’agrégations: comment les écrire et comment ils sont liés à vos query.

7.1. COMPRENDRE L’ANATOMIE D’UNE AGREGATION

Toutes les agrégations, quel que soit leur type, suivent certaines règles:

  • Vous les définissez dans la même requête JSON que vos requêtes et vous les marquez par les mots clés: aggregations, ou aggs. Vous devez donner à chacun un nom et spécifier le type et les options spécifiques à ce type.
  • Ils fonctionnent sur les résultats de votre requête. Les documents qui ne correspondent pas à votre requête ne sont pas comptabilisés, à moins que vous ne les incluiez dans l’agrégation globale, qui est une agrégation de compartiment qui sera traitée plus loin dans ce chapitre.
  • Vous pouvez filtrer davantage les résultats de votre requête, sans influencer les agrégations. Pour ce faire, nous allons vous montrer comment utiliser les filtres de publication. Par exemple, lorsque vous recherchez un mot clé dans une boutique en ligne, vous pouvez créer des statistiques sur tous les articles correspondants, mais utilisez des filtres de publication pour afficher uniquement les résultats présents en stock.

Jetons un coup d’œil à l’agrégation terms, que vous avez déjà vue dans l’introduction de ce chapitre. L’exemple d’utilisation suivant consistait à obtenir les sujets les plus populaires (balises) pour les groupes existants de votre site get-together. Nous utiliserons cette même agrégation de termes pour explorer les règles que toutes les agrégations doivent respecter.

7.1.1. Structure d’une query d’agrégation

Dans la figure 7.1, vous allez exécuter une agrégation de termes qui vous donnera les balises les plus fréquentes dans les groupes de rencontres (get-together). La structure de cette agrégation terms s’appliquera à toute autre agrégation.

Pour que la liste de ce chapitre fonctionne, vous devez indexer le jeu de données exemple à partir des exemples de code fournis avec le livre, situés à l’adresse https://github.com/dakrone/elasticsearch-in-action.

  • Au niveau supérieur, il y a la clé aggregations, qui peut être abrégée en aggs.
  • Au niveau suivant, vous devez donner un nom à l’agrégation. Vous pouvez voir ce nom dans la réponse. Cela est utile lorsque vous utilisez plusieurs agrégations dans la même requête afin de pouvoir facilement voir la signification de chaque ensemble de résultats.
  • Enfin, vous devez spécifier le type d’agrégation comme ici: terms et l’option spécifique. Dans ce cas, vous aurez le nom du champ.

La requête d’agrégation de la figure 7.1 attaque le endpoint _search, exactement comme les requêtes que vous avez vues dans les chapitres précédents. En fait, vous obtenez également 10 résultats de groupe. Tout cela parce qu’aucune query n’a été spécifiée, ce qui exécutera par defaut la query match_all que vous avez vue au chapitre 4. Votre agrégation s’exécutera donc sur tous les documents du groupe. L’exécution d’une query différente obligera l’agrégation à s’exécuter dans un ensemble de documents différent. De toute façon, vous obtenez 10 résultats de ce type car la taille par défaut est 10. Comme vous l’avez vu dans les chapitres 2 et 4, vous pouvez modifier la taille à partir de l’URI ou du corps de votre requête.



Les agrégations et field data
Lorsque vous effectuez une simple recherche, la recherche s’effectue rapidement en raison de la nature de l’index inversé: vous avez un nombre limité de termes à rechercher et Elasticsearch identifie les documents contenant ces termes et renvoie les résultats. Une agrégation, par contre, doit fonctionner avec les termes de chaque document correspondant à la requête. Il nécessite un mapping entre les identifiants du document et les termes, à l’opposé de l’index inversé, qui mappe les termes aux documents.

Par défaut, Elasticsearch « désinverse » l’index inversé dans les field data, comme expliqué au chapitre 6, section 6.10. Plus le nombre de termes traités est élevé, plus les field data utiliseront de la mémoire. C’est pourquoi vous devez vous assurer de donner à Elasticsearch un assez grand tas (Pile), en particulier lorsque vous effectuez des agrégations sur un grand nombre de documents ou si vous analysez des champs et que vous avez plus d’un terme par document. Pour les champs not_analyzed, vous pouvez utiliser les doc_values pour que cette structure de données non inversée soit construite au moment de l’index et stockée sur le disque. Vous trouverez plus de détails sur les field_data et les doc_values au chapitre 6, section 6.10.



7.1.2. Les agrégations s’exécutent sur les résultats de la requête

Le calcul de métriques sur l’ensemble du jeu de données n’est qu’un des cas d’utilisation possibles pour les agrégations. Souvent, vous souhaitez calculer des métriques dans le contexte d’une requête. Par exemple, si vous recherchez des groupes à Denver, vous souhaiterez probablement voir les tags les plus populaires pour ces groupes uniquement. Comme vous le verrez dans la figure suivante, il s’agit du comportement par défaut des agrégations. Contrairement à la figure 7.1, où la requête implicite était match_all, dans la figure suivante, vous interrogez «Denver» dans le champ location, et les agrégations ne concerneront que des groupes de Denver.

Rappelez-vous que dans le chapitre 4 vous pouviez utiliser les paramètres from et size de votre requête pour contrôler la pagination des résultats. Ces paramètres n’ont aucune influence sur les agrégations, car celles-ci s’exécutent toujours sur tous les documents correspondant à une requête.

Si vous souhaitez limiter davantage les résultats des requêtes sans restreindre également les agrégations, vous pouvez utiliser des filtres de publication(post filters). Nous discuterons de ces filtres et de la relation qu’ils ont avec les agrégations en général dans la section suivante.

7.1.3. Filtres et agrégations

Au chapitre 4, vous avez constaté que pour la plupart des types de requête, il existe un filtre équivalent. Les filtres ne calculant pas les scores et pouvant être mis en cache, ils sont plus rapides que leurs homologues de requête. Vous avez également appris que vous devez wrapper (envelopper) vos filtres dans des filtered query, comme ceci:

L’utilisation du filtre de cette manière est utile pour les performances globales des requêtes, car le filtre s’exécute en premier. Ensuite, la requête (qui requiert généralement davantage de performances) ne s’exécute que sur les documents correspondant au filtre. En ce qui concerne les agrégations, elles ne fonctionnent que sur les documents correspondant à la requête filtrée globale, comme le montre la figure 7.3.

«Rien de nouveau à ce jour», pourriez-vous dire. « La requête filtrée se comporte comme toute autre requête en matière d’agrégation », et vous avez raison. Mais il existe aussi une autre façon d’exécuter des filtres: en utilisant un post filter, ou filtre de publication, qui s’exécutera après la requête et indépendamment de l’agrégation. La requête suivante donnera les mêmes résultats que la requête filtrée précédente:

Comme illustré à la figure 7.4, le post filter diffère du filtre dans la requête filtrée de deux manières:

  • Performance— Le filtre de publication (post filter) est exécuté après la requête, en s’assurant que celle-ci s’exécutera sur tous les documents et qu’il ne s’exécute que sur les documents correspondant à la requête. La demande globale est généralement plus lente que la requête filtrée équivalente, où le filtre est exécuté en premier.
  • Ensemble de documents traité par les agrégations: si un document ne correspond pas au post filter, il sera quand même comptabilisé par les agrégations.

Maintenant que vous comprenez les relations entre les requêtes, les filtres et les agrégations, ainsi que la structure globale d’une requête d’agrégation, nous pouvons approfondir l’exploration des aggregations et en explorer les différents types. Nous commencerons par les agrégations de mesures, puis par agrégations de compartiments, puis nous discuterons de la manière de les combiner pour obtenir des informations puissantes à partir de vos données en temps réel.

7.2. AGRÉGATIONS DE MÉTRIQUES

Les agrégations de métriques extraient des statistiques à partir de groupes de documents ou, comme nous le verrons à la section 7.4, des compartiments de documents provenant d’autres agrégations.

Ces statistiques sont généralement effectuées sur des champs numériques, tels que le prix minimum ou moyen. Vous pouvez obtenir chacune de ces statistiques séparément ou vous pouvez les rassembler via l’agrégation de statistiques stats. Des statistiques plus avancées, telles que la somme des carrés ou l’écart type, sont disponibles via l’agrégation extended_stats.

Pour les champs numériques et non numériques, vous pouvez obtenir le nombre de valeurs uniques à l’aide de l’agrégation de cardinality, ce qui sera présenté à la section 7.2.3.

7.2.1. Statistiques

Nous commencerons par examiner les agrégations de métriques en obtenant des statistiques sur le nombre de participants à chaque événement.

Parmi nos données, vous pouvez voir que les documents d’événement contiennent un tableau de participants. Vous pouvez calculer le nombre de participants au moment de la requête grâce à un script, que nous montrerons dans la figure 7.3. Nous avons traité des scripts au chapitre 3, lorsque vous utilisiez des scripts pour mettre à jour des documents. En général, avec les requêtes Elasticsearch, vous pouvez créer un champ script dans lequel vous insérez un petit morceau de code qui renvoie une valeur pour chaque document. Dans ce cas, la valeur sera le nombre d’éléments du tableau de participants.



La flexibilité des scripts a un prix

Les scripts sont flexibles en matière de requête, mais vous devez être conscient des limites en termes de performances et de sécurité.

Même si la plupart des types d’agrégation vous permettent de les utiliser, les scripts ralentissent les agrégations car ils doivent être exécutés sur tous les documents. Pour éviter d’avoir à exécuter un script, vous pouvez effectuer le calcul au moment de l’index. Dans ce cas, vous pouvez extraire le nombre de participants pour chaque événement et l’ajouter à un champ séparé avant de l’indexer. Nous parlerons davantage de performance au chapitre 10.

Dans la plupart des déploiements Elasticsearch, l’utilisateur spécifie une query string et il appartient à l’application côté serveur de construire la requête à partir de celle-ci. Mais si vous autorisez les utilisateurs à spécifier tout type de requête, y compris les scripts, il est possible que quelqu’un l’exploite et exécute un code malveillant. C’est pourquoi, en fonction de votre version d’Elasticsearch, l’exécution de scripts en ligne, comme dans la figure 7.3 (appelée script dynamique), est désactivée. Pour l’activer, définissez script.disable_dynamic: false dans elasticsearch.yml.



Dans la figure suivante, vous demanderez des statistiques sur le nombre de participants à tous les événements. Pour obtenir le nombre de participants dans le script, vous utiliserez  doc [‘participants’].values pour obtenir le tableau des participants. L’ajout de la propriété lenght permettra de retourner leur numéro.

Vous pouvez constater que vous récupérez le nombre minimum de participants par événement, ainsi que le nombre maximum, la somme et la moyenne. Vous obtenez également le nombre de documents sur lesquels ces statistiques ont été calculées.

Si vous n’avez besoin que d’une de ces statistiques, vous pouvez l’obtenir séparément. Par exemple, vous calculerez le nombre moyen de participants par événement grâce à l’agrégation moyenne dans la figure suivante.

Semblable à l’agrégation avg, vous pouvez obtenir les autres métriques via les agrégations min, max, sum et value_count. Vous devez remplacer avg de la figure 7.4 par le nom de l’agrégation requise. L’avantage de statistiques distinctes est qu’Elasticsearch ne perdra plus son temps à calculer des métriques inutiles.

7.2.2. Statistiques avancées

Outre les statistiques collectées par l’agrégation de statistiques stats, vous pouvez obtenir la somme des carrés, de la variance et de l’écart type de votre champ numérique en exécutant l’agrégation extended_stats, comme indiqué dans la figure suivante.

Toutes ces statistiques sont calculées en examinant toutes les valeurs du jeu de documents correspondant à la requête. Elles sont donc précises à 100% tout le temps. Nous examinerons ensuite certaines statistiques qui utilisent des algorithmes d’approximation, échangeant une partie de la précision contre la vitesse et la consommation de mémoire.

7.2.3. Statistiques approximatives

Certaines statistiques peuvent être calculées avec une bonne précision (mais pas à 100%) en regardant certaines des valeurs de vos documents. Cela limitera à la fois leur temps d’exécution et leur consommation de mémoire.

Nous verrons ici comment obtenir deux types de statistiques de ce type à partir d’Elasticsearch: les centiles et la cardinalité. Les percentiles (centiles) sont des valeurs en dessous desquelles vous pouvez trouver x% du total, x étant le centile donné. Ceci est utile, par exemple, lorsque vous avez une boutique en ligne: vous enregistrez la valeur de chaque panier et vous voulez voir dans quelle gamme de prix se trouvent la plupart des paniers. La plupart de vos utilisateurs n’achètent peut-être qu’un ou deux objets, mais les 10% les plus riches achètent beaucoup d’articles et génèrent la majeure partie de vos revenus.

La cardinalité est le nombre de valeurs uniques dans un champ. Ceci est utile, par exemple, lorsque vous voulez le nombre d’adresses IP uniques accédant à votre site Web.

Centiles
Pour les centiles, pensez à nouveau au nombre de participants aux événements et déterminez le nombre maximal de participants que vous considérerez comme normal et le nombre que vous jugerez élevé. Dans la figure 7.6, vous calculerez le 80e centile et le 99e. Vous considérerez que les nombres inférieurs au 80ème sont normaux et ceux inférieurs à 99ème maximum, et vous ignorerez le 1% supérieur, car ils sont exceptionnellement élevés.

Pour ce faire, vous utiliserez l’agrégation de centiles percentiles et définissez le tableau de pourcentages percents sur 80 et 99 afin d’obtenir ces centiles spécifiques.

Pour les petits ensembles de données tels que ceux dont vous disposez, vous avez une précision de 100%, mais cela peut ne pas arriver avec de grands ensembles de données en production. Avec les paramètres par défaut, vous avez une précision de plus de 99,9% pour la plupart des ensembles de données, et ceci pour la plupart des centiles. Le centile spécifique est important, car l’exactitude est au plus bas pour le 50e centile et, à mesure que l’on se rapproche de 0 ou de 100, elle s’améliore

Vous pouvez échanger la mémoire pour plus de précision en augmentant le paramètre compression par rapport au paramètre par défaut 100. La consommation mémoire augmente proportionnellement à la compression, ce qui contrôle le nombre de valeurs prises en compte lors de l’approximation des centiles.

Il existe également une agrégation percentile_ranks qui vous permet de faire le contraire – spécifiez un ensemble de valeurs – et vous obtiendrez le pourcentage correspondant de documents ayant jusqu’à ces valeurs:

Cardinalité
Pour la cardinalité, imaginons que vous souhaitiez connaître le nombre de membres uniques de votre site de rencontre get-together. La figure suivante montre comment procéder avec l’agrégation cardinality.

Comme l’agrégation percentiles, l’agrégation cardinality est approximative. Pour comprendre l’intérêt de tels algorithmes d’approximation, examinons de plus près l’alternative. Avant que l’agrégation de cardinalité ne soit introduite dans la version 1.1.0, le moyen courant d’obtenir la cardinalité d’un champ consistait à exécuter l’agrégation terms que vous avez vue à la section 7.1. Étant donné que l’agrégation terms obtient les comptes de chaque terme pour les N principaux termes, N étant le paramètre de taille configurable, si vous spécifiez une taille suffisamment grande, vous pouvez obtenir tous les termes uniques. Les compter vous donnera la cardinalité.

Malheureusement, cette approche ne fonctionne que pour les champs avec une cardinalité relativement faible et un nombre de documents faible. Sinon, exécuter une agrégation de termes avec une taille énorme nécessite beaucoup de ressources:

  • Mémoire— Tous les termes uniques doivent être chargés en mémoire pour être comptés.
  • CPU – Ces termes doivent être retournés dans l’ordre; Par défaut, la commande indique combien de fois chaque terme est utilisé.
  • Réseau – A partir de chaque fragment, le large éventail de termes uniques triés doit être transféré au nœud qui a reçu la requête du client. Ce nœud doit également fusionner des tableaux par fragment en un seul grand tableau et le transférer au client.

C’est ici qu’interviennent les algorithmes d’approximation. Le champ cardinalité fonctionne avec un algorithme appelé HyperLogLog ++ qui hache les valeurs du champ que vous souhaitez examiner et utilise le hachage pour approcher la cardinalité. Il ne charge en même temps qu’une partie de ce hache en mémoire, de sorte que l’utilisation de la mémoire sera constante quel que soit le nombre de termes que vous avez.

Pour plus de détails sur l’algorithme HyperLogLog ++, consultez l’article original de Google: http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/en/us/pubs/archive/40671.pdf.



Mémoire et cardinalité
Nous avons dit que l’utilisation de la mémoire de l’agrégation cardinality est constante, mais quelle serait sa taille? Vous pouvez le configurer via le paramètre precision_threshold. Plus le seuil est élevé, plus les résultats sont précis, mais plus la mémoire utilisée est importante. Si vous exécutez l’agrégation cardinality seule, cela prendra environ 8 octets de mémoire * precision_threshold pour chaque fragment touché par la requête.

L’agrégation cardinality, comme toutes les autres agrégations, peut être imbriquée dans une agrégation de compartiment. Lorsque cela se produit, l’utilisation de la mémoire est encore multipliée par le nombre de compartiments générés par les agrégations parentes.



Dans la plupart des cas, le paramètre precision_threshold par défaut fonctionnera bien car il offre un bon compromis entre l’utilisation de la mémoire et la précision, et il s’ajuste lui-même en fonction du nombre de compartiments.



Nous examinerons ensuite le choix des agrégations multi-compartiments. Mais avant d’y aller, le tableau 7.1 vous donne un aperçu rapide de chaque agrégation de métriques et du cas d’utilisation typique.

7.3. AGREGATIONS A PLUSIEURS BUCKETS

Comme vous l’avez vu dans la section précédente, les agrégations de métriques consistent à prendre tous vos documents et à générer un ou plusieurs nombres qui les décrivent. Les agrégations multi-compartiments consistent à prendre ces documents et à les placer dans des compartiments, comme le groupe de documents correspondant à chaque balise. Ensuite, pour chaque compartiment, vous obtiendrez un ou plusieurs numéros décrivant le compartiment, par exemple, en comptant le nombre de groupes pour chaque balise.

Jusqu’à présent, vous avez exécuté des agrégations de métriques sur tous les documents correspondant à la requête. Vous pouvez considérer ces documents comme un seul grand paquet(bucket). D’autres agrégations génèrent de tels compartiments: par exemple, si vous indexez les logs et disposez d’un champ représentant le code pays, vous pouvez effectuer une agrégation de termes sur celui-ci pour créer un compartiment de documents pour chaque pays. Comme vous le verrez à la section 7.4, vous pouvez imbriquer des agrégations: par exemple, une agrégation  cardinality pourrait s’exécuter sur les compartiments créés par l’agrégation terms pour vous donner le nombre de visiteurs uniques par pays.

Pour l’instant, voyons quels types d’agrégations multi-compartiments sont disponibles et où elles sont généralement utilisées:

  • Les agrégations terms vous permettent de déterminer la fréquence de chaque terme dans vos documents. L’agrégation terms, que vous avez déjà vue plusieurs fois, vous redonne le nombre de fois où chaque terme apparaît. C’est utile pour comprendre des choses comme des affiches fréquentes sur un blog ou des tags populaires. Il y a aussi l’agrégation significant_terms, qui vous redonne la différence entre l’occurrence d’un terme dans l’ensemble de l’index et son apparition dans les résultats de votre requête. Ceci est utile pour suggérer des termes significatifs pour le contexte de recherche, tels que «elasticsearch» le serait pour le contexte de «moteur de recherche».
  • Les agrégations range créent des compartiments en fonction de la manière dont les documents se situent dans quelle plage numérique, de dates ou d’adresses IP…etc. Ceci est utile lors de l’analyse de données pour lesquelles l’utilisateur a des attentes fixes. Par exemple, si quelqu’un recherche un ordinateur portable dans une boutique en ligne, vous connaissez les fourchettes de prix les plus populaires.
  • Les agrégations histogrammes, numériques ou par date, sont similaires aux agrégations range, mais au lieu de vous demander de définir chaque plage, vous devez définir un intervalle, et Elasticsearch construira des compartiments basés sur cet intervalle. Ceci est utile lorsque vous ne savez pas où l’utilisateur est susceptible de regarder. Par exemple, vous pouvez afficher un graphique indiquant le nombre d’événements survenant chaque mois.
  • Les agrégations imbriquées, inversées et enfants vous permettent d’effectuer des agrégations entre les relations de documents. Nous en discuterons au chapitre 8 lorsque nous parlerons de relations imbriquées et parent-enfant.
  • Les agrégations de géo-distance et de grille geohash vous permettent de créer des compartiments basés sur la géolocalisation. Nous les montrerons à l’annexe A, consacrée à la géolocalisation.

La figure 7.5 présente un aperçu des types d’agrégations à plusieurs compartiments dont nous allons parler ici.

Voyons ensuite chacune de ces agrégations multi-compartiments et voyons comment les utiliser.

7.3.1. Agrégations terms

Nous avons d’abord examiné l’agrégation de termes dans la section 7.1 à titre d’exemple afin de montrer la façon dont fonctionnent toutes les agrégations en général. Le cas d’utilisation typique consiste à obtenir le X le plus fréquent, X étant un champ de votre document, tel que le nom d’un utilisateur, une balise ou une catégorie. Étant donné que l’agrégation de termes compte chaque terme et non chaque valeur de champ, vous devez normalement exécuter cette agrégation sur un champ non analysé, car vous souhaitez que les «big data» soient comptées une fois, et non une fois pour «big» et une fois pour «data».

Vous pouvez utiliser l’agrégation de termes pour extraire les termes les plus fréquents d’un champ analysé, comme la description d’un événement. Vous pouvez utiliser ces informations pour générer un nuage de mots, similaire à celui de la figure 7.6. Assurez-vous simplement que vous avez suffisamment de mémoire pour charger tous les champs en mémoire si vous avez plusieurs documents ou si les documents contiennent de nombreux termes.

Par défaut, l’ordre selon lesquels les termes sont classés est décroissant et fonction de leur nombre. Mais vous pouvez classer les termes par ordre croissant ou selon d’autres critères, tels que le nom lui-même. La liste suivante montre comment répertorier les balises de groupe classées par ordre alphabétique à l’aide de la propriété order.

Si vous imbriquez une agrégation de métriques dans votre agrégation de termes, vous pouvez également trier les termes en fonction de la métrique. Par exemple, vous pouvez utiliser l’agrégation de métriques moyenne sous l’agrégation de vos balises pour obtenir le nombre moyen de membres du groupe par tag( voir figure 7.8). Vous pouvez également classer les tags en fonction du nombre de membres en indiquant le nom de votre agrégation de metrics, par exemple avg_members: desc (au lieu de _term: asc, comme indiqué dans la figure 7.8).

Quels termes inclure dans la réponse
Par défaut, l’agrégation de termes ne renverra que les 10 premiers termes en utilisant l’ordre que vous avez sélectionné. Vous pouvez toutefois modifier ce nombre via le paramètre size. Si vous définissez la taille sur 0, vous obtiendrez tous les termes, mais il est dangereux de l’utiliser avec un champ de cardinalité élevée, car renvoyer un résultat très volumineux nécessite beaucoup de temps de traitement et risque de saturer votre réseau.

Pour récupérer les 10 termes principaux (ou le nombre de termes que vous avez configuré dans le paramètre size), Elasticsearch doit obtenir un nombre de termes (configurable via shard_size) de chaque fragment et agréger les résultats. Le processus est illustré à la figure 7.7, avec shard_ size et size réglés sur 2 pour plus de clarté.

Ce mécanisme implique que vous pouvez obtenir des compteurs inexacts pour certains termes si ces termes ne parviennent pas au sommet de chaque fragment individuel. Il peut même en résulter des termes manquants, comme dans la figure 7.7, où « lucene », avec une valeur totale de 7, ne figure pas dans les 2 tags principaux car le mot clé ne figure pas parmi les 2 premiers pour chaque fragment.

Vous pouvez obtenir des résultats plus précis en définissant une taille shard_size plus importante, comme illustré à la figure 7.8. Mais cela rendra les agrégations plus coûteuses (surtout si vous les imbriquez) car il y a plus de paquets(bucket)qui doivent être conservés en mémoire.

Pour avoir une idée de l’exactitude des résultats, vous pouvez vérifier les valeurs au début de la réponse de l’agrégation:

Le premier chiffre représente la marge d’erreur du scénario le plus défavorable. Par exemple, si le nombre minimal pour un terme renvoyé par un fragment est 5, il est possible qu’un terme apparaissant quatre fois dans ce fragment ait été omis. Si ce terme devait apparaître dans les résultats finaux, il s’agirait du pire des cas parmis les 4. Le total de ces nombres pour tous les fragments constitue doc_count_error_upper_bound. Pour nos exemples de code, ce nombre est toujours égal à 0, car nous ne disposons que d’un fragment. Les termes les plus utilisés pour ce fragment sont identiques aux termes globaux.

Le deuxième nombre est le nombre total de termes qui n’ont pas atteint le sommet(atteint le top du classement afin de pouvoir être retourné).

Vous pouvez obtenir une valeur doc_count_error_upper_bound pour chaque terme en définissant show_term_doc_count_error sur true. Cela prendra l’erreur du scénario le plus défavorable par terme: par exemple, si «big data» est renvoyé par un fragment, vous savez que c’est la valeur exacte. Mais si un autre fragment ne renvoie pas du tout «big data», le pire des scénarios est qu’il existe en réalité un «big data» dont la valeur se situe juste en dessous du dernier terme renvoyé. L’ajout de ces numéros d’erreur pour les fragments ne renvoyant pas ce terme constitue le doc_count_error _upper_bound par terme.

À l’autre extrémité du spectre de précision, vous pouvez envisager des termes avec une basse fréquence, donc non pertinents et les exclure entièrement du jeu de résultats. Ceci est particulièrement utile lorsque vous triez les termes avec autre chose que leur fréquence, ce qui rend probable l’apparition de termes peu fréquents, mais vous ne souhaitez pas polluer les résultats avec des résultats non pertinents, tels que des fautes de frappe. Pour ce faire, vous devez modifier le paramètre min_doc_count. Sa valeur par défaut est 1. Si vous souhaitez couper ces termes avec de basses fréquences au niveau des fragment, vous pouvez utiliser l’attribut shard_min_doc_count.

Enfin, vous pouvez inclure et exclure des termes spécifiques du résultat. Pour ce faire, utilisez les options include et exclude et fournissez des expressions régulières en tant que valeurs. Utiliser seulement l’inclusion inclura uniquement les termes correspondant au modèle; l’exclusion seule inclura des termes qui ne correspondent pas. L’exclusion aura la priorité lors de l’utilisation des 2: les termes inclus correspondant au modèle d’inclusion mais qui ne correspondent pas au modèle d’exclusion.

La figure suivante montre comment renvoyer uniquement les compteurs des tags contenant «recherche».



Mode de collecte
Par défaut, Elasticsearch effectue toutes les agrégations en un seul passage. Par exemple, si une agrégation de termes et une agrégation de cardinalité sont imbriquées, Elasticsearch crée un compartiment pour chaque terme, calcule la cardinalité de chaque compartiment, trie ces compartiments et renvoie le X supérieur.

Cela fonctionne bien dans la plupart des cas d’utilisation, mais cela prendra beaucoup de temps et de mémoire si vous avez beaucoup de compartiments et beaucoup de sous-agrégations, en particulier si une sous-agrégation est également une agrégation à plusieurs compartiments. Dans ce cas, une approche en deux passages sera préférable: commencez par créer les compartiments de l’agrégation de niveau supérieur, triez et mettez en cache le X supérieur, puis calculez les sous-agrégations uniquement sur ces X.

Vous pouvez contrôler l’approche utilisée par Elasticsearch en définissant le collect_mode. La valeur par défaut est depth_first, et l’approche en deux passes est width_first.



significant_terms
L’agrégation significant_terms est utile si vous souhaitez voir quels termes ont des fréquences plus élevées que la normale dans les résultats de votre recherche actuelle. Prenons l’exemple des groupes de rencontre (get-together): dans tous les groupes, le terme clojure peut ne pas apparaître assez souvent pour être considéré. Supposons qu’il apparaisse 10 fois sur 1 000 000 de termes (0,0001%). Si vous restreignez votre recherche à Denver, disons qu’elle apparaît 7 fois sur 10 000 termes (0,007%). Le pourcentage est nettement plus élevé qu’auparavant et indique une forte communauté Clojure à Denver par rapport au reste de la zone de recherche. Peu importe que d’autres termes tels que programmation ou devops aient une fréquence absolue beaucoup plus élevée.

L’agrégation significant_terms ressemble beaucoup à l’agrégation de termes en ce sens qu’elle compte les termes. Mais les compartiments résultants sont classés par score, ce qui représente la différence de pourcentage entre les documents de premier plan (0,007% dans l’exemple précédent) et les documents de fond (0,0001%). Les documents de premier plan sont ceux correspondant à votre requête et les documents d’arrière-plan sont tous les documents de l’index.

Dans la figure suivante, vous allez essayer de savoir quels utilisateurs du site de rendez-vous ont une préférence similaire à Lee pour les événements. Pour ce faire, vous rechercherez des événements auxquels Lee participera et utiliserez l’agrégation significant_terms pour voir à quel événement les utilisateurs participent le plus, par rapport à l’ensemble des événements auxquels ils participent.

Comme vous l’avez peut-être deviné dans la figure, l’agrégation significant_terms a la même size, shard_size, min_doc_count, shard_min_doc_count, les options d’exclusion que l’agrégation de termes, ce qui vous permet de contrôler les termes que vous récupérez. En plus de ceux-ci, il vous permet de modifier les documents d’arrière-plan de tous les documents de l’index en ceux qui correspondent à un filtre défini dans le paramètre background_filter. Par exemple, vous savez peut-être que Lee participe uniquement à des événements technologiques. Vous pouvez donc les filtrer pour vous assurer que les événements sans rapport avec lui ne sont pas pris en compte.

Les agrégations terms et significant_terms fonctionnent bien pour les champs de chaîne de charactères. Pour les champs numériques, les agrégations range et histogram sont plus pertinentes et nous les examinerons ensuite.

7.3.2. Agrégations range

L’agrégation term est le plus souvent utilisée avec des chaînes de charactères, mais elle fonctionne également avec des valeurs numériques. Ceci est utile lorsque vous avez une cardinalité faible, comme lorsque vous voulez donner des comptes sur le nombre d’ordinateurs portables dotés de deux ans de garantie, combien en ont trois, etc.

Avec des champs de haute cardinalité, tels que les âges ou les prix, vous recherchez probablement des plages de valeurs. Par exemple, vous voudrez peut-être savoir combien de vos utilisateurs ont entre 18 et 39 ans, combien entre 40 et 60 ans, etc. Vous pouvez toujours le faire avec l’agrégation de termes, mais cela va être fastidieux: dans votre application, vous devrez ajouter des compteurs pour les âges de 18, 19, et ainsi de suite jusqu’à ce que vous atteigniez 39 ans pour obtenir le premier compartiment. Et si vous souhaitez ajouter des sous-agrégations, comme celles que vous verrez plus loin dans ce chapitre, la situation deviendra encore plus compliquée.

Pour résoudre ce problème pour les valeurs numériques, vous avez l’agrégation range. Comme son nom l’indique, vous donnez les plages numériques que vous souhaitez et il comptera les documents avec des valeurs comprises dans chaque compartiment. Vous pouvez utiliser ces compteurs pour représenter les données de manière graphique, par exemple avec un graphique à secteurs, comme illustré à la figure 7.9.

Rappelez-vous du chapitre 3 que les dates sont stockées en tant que type long dans Elasticsearch, représentant l’heure UNIX en millisecondes. Pour utiliser les plages de dates, vous disposez d’une variante de l’agrégation range appelée date_range.

Agrégation range

Revenons à notre exemple de site de rencontre et analysons les événements en fonction du nombre de participants. Vous allez le faire avec l’agrégation range et lui donner un tableau de plages. Il ne faut pas oublier que la valeur minimale de la plage (la clé from) est incluse dans le compartiment, alors que la valeur maximale (to) est exclue. Dans la figure 7.11, vous aurez trois catégories:

  • Événements avec moins de quatre membres
  • Événements avec au moins quatre membres mais moins de six
  • Événements avec au moins six membres

Les plages ne doivent pas nécessairement être adjacentes; ils peuvent être séparés ou se chevaucher. Dans la plupart des cas, il est logique de couvrir toutes les valeurs, mais ce n’est pas nécessaire.

Vous pouvez voir dans la figure que vous n’avez pas à spécifier à la fois from et to pour chaque plage de l’agrégation. L’omission de l’un de ces paramètres supprimera la limite respective, ce qui vous permettra de rechercher tous les événements de moins de quatre membres ou d’au moins six.

Agrégation date_range
Comme vous pouvez l’imaginer, l’agrégation date_range fonctionne de la même manière que l’agrégation range, sauf que vous placez des dates dans vos définitions de plages. Et à cause de cela, vous devez définir le format de date pour qu’Elasticsearch sache comment traduire la chaîne que vous lui donnez en heure UNIX numérique, vu que c’est ce qui est véritablement stocké dans le système(timestamp).

Dans la figure suivante, vous divisez les événements en deux catégories: avant juillet 2013 et à compter de juillet 2013. Vous pouvez utiliser une approche similaire pour compter les événements futurs et les événements passés, par exemple.

Si la valeur du champ format vous semble familière, c’est parce que c’est la même annotation Joda Time que celle que vous avez vue au chapitre 3 lorsque vous avez défini les formats de date dans le mapping. Pour connaître la syntaxe complète, vous pouvez consulter la documentation de DateTimeFormat: http://joda-time.sourceforge.net/apidocs/org/joda/time/format/DateTimeFormat.html .

7.3.3. Agrégations histogram

Pour traiter les plages numériques, vous avez également des agrégations d’histogrammes. Celles-ci ressemblent beaucoup aux agrégations de plages que vous venez de voir, mais au lieu de définir manuellement chaque plage, vous définissiez un intervalle fixe et Elasticsearch créerait les plages pour vous. Par exemple, si vous souhaitez définir des groupes d’âge dans les documents relatifs aux personnes, vous pouvez définir un intervalle de 10 (années) et obtenir des compartiments tels que 0-10 (excluant 10), 10-20 (excluant 20), etc.

À l’instar de l’agrégation range, l’agrégation histogram a une variante qui fonctionne avec les dates, appelée agrégation date_histogram. Ceci est utile, par exemple, lors de la création de diagrammes d’histogramme indiquant le nombre d’emails envoyés chaque jour sur une liste de diffusion.

Agrégation d’histogramme
L’exécution d’une agrégation d’histogramme est similaire à l’exécution d’une agrégation de plages. Vous venez de remplacer le tableau de plages par un intervalle, et Elasticsearch construira des plages en commençant par la valeur minimale, en ajoutant l’intervalle jusqu’à ce que la valeur maximale soit incluse. Par exemple, dans la figure suivante, vous spécifiez un intervalle de 1 et du coup indiquez combien d’événements ont trois participants, combien en ont quatre et combien en ont cinq.

Comme pour l’agrégation de termes, l’agrégation d’histogrammes vous permet de spécifier une valeur min_doc _count, ce qui est utile si vous souhaitez que les compartiments contenant peu de documents soient ignorés. min_doc_count est également utile si vous souhaitez afficher des compartiments vides. Par défaut, s’il existe un intervalle entre les valeurs minimale et maximale dépourvue de documents, cet intervalle sera totalement omis. Définissez min_doc_count sur 0 et ces intervalles apparaîtront toujours avec un nombre de documents égal à 0.

Agrégation d’histogramme de date
Comme vous vous en doutez, vous utiliserez l’agrégation date_histogram comme celle de l’histogramme, mais vous insérerez une date dans le champ d’intervalle. Cette date serait spécifiée dans la même annotation Joda Time que l’agrégation date_range, avec des valeurs telles que 1M ou 1,5h. Par exemple, la figure suivante donne la répartition des événements qui se produisent chaque mois.

Comme pour l’agrégation d’histogramme classique, vous pouvez utiliser l’option min_doc_count pour afficher les compartiments vides ou ommettre les paquets(buckets) contenant juste quelques documents

Vous avez probablement remarqué que l’agrégation date_histogram a deux points communs avec toutes les autres agrégations multi-compartiments:

  • Il compte les documents ayant certains termes.
  • Il crée des pacquets de documents entrant dans chaque catégorie.

Les compartiments eux-mêmes ne sont utiles que lorsque vous imbriquez d’autres agrégations dans une agrégation à plusieurs compartiments. Cela vous permet d’avoir un aperçu plus approfondi de vos données et nous examinerons l’imbrication des agrégations dans la section suivante. Tout d’abord, prenez le temps de regarder le tableau 7.2, qui vous donne un aperçu rapide des agrégations à plusieurs compartiments et de leurs utilisations habituelles.

La liste n’est pas exhaustive, mais elle inclut les principaux types d’agrégation et leurs options. Vous pouvez consulter la documentation [1] pour une liste complète. De plus, les agrégations géographiques sont traitées dans l’annexe A et les agrégations imbriquées et enfants au chapitre 8.

7.4. AGRÉGATIONS DE NIDIFICATION (IMBRIQUEES)

Le véritable pouvoir des agrégations réside dans le fait que vous pouvez les combiner. Par exemple, si vous avez un blog et que vous enregistrez chaque accès à vos publications, vous pouvez utiliser l’agrégation de termes pour afficher les publications les plus consultées. Mais vous pouvez également imbriquer une agrégation de cardinalité sous cette agrégation de termes et afficher le nombre de visiteurs uniques pour chaque publication.

Comme vous pouvez l’imaginer, les agrégations d’imbrication ouvrent une nouvelle gamme de possibilités pour l’exploration de données. La nidification est la principale raison pour laquelle les agrégations sont apparues dans Elasticsearch en remplacement des facettes, car elles ne pouvaient pas être combinées.

Les agrégations multi-compartiments sont généralement le point de départ de l’imbrication. Par exemple, l’agrégation de termes vous permet d’afficher les balises principales des groupes de rencontre; cela signifie que vous aurez un paquet(bucket) de documents pour chaque tag(terme). Vous pouvez utiliser des sous-agrégations pour afficher plus de métriques pour chaque compartiment. Par exemple, vous pouvez indiquer le nombre de groupes créés chaque mois pour chaque balise, comme illustré à la figure 7.10.

Plus loin dans cette section, nous aborderons un cas d’utilisation particulier pour l’imbrication: le regroupement des résultats, qui, contrairement à une recherche classique qui donne les N premiers résultats par pertinence, vous donne les N premiers résultats pour chaque ensemble de documents généré par l’agrégation parente. Supposons que vous ayez une boutique en ligne et que quelqu’un recherche «Windows». Normalement, les résultats triés par pertinence affichent en premier lieu de nombreuses versions du système d’exploitation Windows. Ce n’est peut-être pas la meilleure expérience utilisateur, car à ce stade, il n’est pas encore clair si l’utilisateur cherche à acheter un système d’exploitation Windows, des logiciels conçus pour Windows ou du matériel fonctionnant sous Windows. C’est là que le regroupement des résultats, illustré à la figure 7.11, est très utile: vous pouvez afficher les trois premiers résultats de chaque catégorie de systèmes d’exploitation, de logiciels et de matériels et donner à l’utilisateur une gamme plus étendue de résultats. L’utilisateur peut également vouloir cliquer sur le nom de la catégorie pour limiter la recherche à cette catégorie uniquement.

Dans Elasticsearch, vous pourrez obtenir le regroupement des résultats en utilisant une agrégation spéciale appelée top_hits. Elle récupère les N premiers résultats, triés par score ou par un critère de votre choix, pour chaque compartiment d’une agrégation parente. Cette agrégation parente peut être une agrégation de termes exécutée sur le champ catégorie, comme suggéré dans l’exemple de boutique en ligne de la figure 7.11; nous allons passer en revue cette agrégation spéciale dans la section suivante.

Le dernier cas d’utilisation de la nidification dont nous allons parler est le contrôle du jeu de documents sur lequel vos agrégations sont exécutées. Par exemple, quelle que soit la requête, vous souhaiterez peut-être afficher les tags les plus courants pour les groupes de rencontre créés au cours de la dernière année. Pour ce faire, vous utiliserez l’agrégation filter, qui crée un compartiment de documents correspondant au filtre fourni, dans lequel vous pouvez imbriquer d’autres agrégations.

7.4.1. Imbrication d’agrégations multi-compartiments

Pour imbriquer une agrégation dans une autre, il vous suffit d’utiliser la clé d’agrégations ou d’agg au même niveau que le type d’agrégation parent, puis de définir la définition de la sous-agrégation comme valeur. Pour les agrégations multi-compartiments, cela peut être fait indéfiniment. Par exemple, dans la figure suivante, vous utiliserez l’agrégation de termes pour afficher les tags les plus utilisées. Pour chaque tag, vous utiliserez l’agrégation date_histogram pour indiquer le nombre de groupes créés chaque mois. Enfin, pour chaque compartiment de ces groupes, vous utiliserez l’agrégation range pour indiquer combien de groupes ont moins de trois membres et combien en ont au moins trois.

Vous pouvez toujours imbriquer une agrégation de métrique dans une agrégation de compartiment. Par exemple, si vous souhaitez utiliser le nombre moyen de membres du groupe au lieu des plages 0–2 et 3+ que vous aviez dans la figure précédente, vous pouvez utiliser l’agrégation avg ou stats.

Top_hits est un type particulier d’agrégation que nous avons promis de couvrir dans la dernière section. Vous obtiendrez les N premiers résultats, triés selon les critères de votre choix, pour chaque compartiment de son agrégation parent. Nous verrons ensuite comment vous utiliserez l’agrégation top_hits pour obtenir le regroupement des résultats.

7.4.2. Imbrication d’agrégations pour obtenir le regroupement des résultats

Le regroupement des résultats est utile lorsque vous souhaitez afficher les meilleurs résultats regroupés par une certaine catégorie. Comme dans Google, lorsque vous obtenez de nombreux résultats sur le même site, vous ne voyez parfois que les trois premiers choix, puis le site suivant est affiché. Vous pouvez toujours cliquer sur le nom du site pour obtenir tous les résultats qui correspondent à votre requête.

C’est à cela que sert le regroupement des résultats: il vous permet de donner à l’utilisateur une meilleure idée de ce qu’il contient. Supposons que vous vouliez montrer à l’utilisateur les événements les plus récents et faire en sorte qu’ils soient plus diversifiés, vous montrerez l’événement le plus récent aux participants les plus fréquents. Vous ferez cela dans la figure suivante en exécutant l’agrégation de termes sur le champ des participants et en imbriquant l’agrégation top_hits.

Au début, il peut sembler étrange d’utiliser des agrégations pour obtenir le regroupement des résultats. Mais maintenant que vous avez appris en quoi consistent les agrégations, vous pouvez constater que ces concepts de compartiments et d’imbrication sont puissants et vous permettent de faire beaucoup plus que de recueillir des statistiques sur les résultats des requêtes. L’agrégation top_hits est un exemple de résultat non statistique des agrégations.

Vous n’êtes pas limité aux seuls résultats de requête lorsque vous exécutez des agrégations; C’est le comportement par défaut, comme vous l’avez appris à la section 7.1, mais vous pouvez le contourner si vous en avez besoin. Par exemple, supposons que vous souhaitiez afficher les tags de publication les plus populaires sur votre blog quelque part dans une barre latérale. Et vous souhaitez afficher cette barre latérale, quelle que soit la recherche de l’utilisateur. Pour ce faire, vous devez exécuter votre agrégation de termes sur toutes les publications de blog, indépendamment de votre requête. C’est là que l’agrégation global devient utile: elle crée un compartiment avec tous les documents de votre contexte de recherche (les index et les types que vous recherchez), faisant en sorte que toutes les autres agrégations imbriquées sous celle-ci fonctionnent avec tous ces documents.

L’agrégation global est l’une des agrégations à un seul compartiment que vous pouvez utiliser pour modifier le jeu de documents utilisé par d’autres agrégations. C’est ce que nous explorerons ensuite.

7.4.3. Utilisation d’agrégations à un seul compartiment

Comme vous l’avez vu à la section 7.1, Elasticsearch exécutera vos agrégations sur les résultats de la requête par défaut. Si vous souhaitez modifier cette valeur par défaut, vous devrez utiliser des agrégations à un seul compartiment. Nous en discuterons ici de trois:

  • global crée un compartiment avec tous les documents des types et index sur lesquels vous recherchez. Cela est utile lorsque vous souhaitez exécuter des agrégations sur tous les documents, quelle que soit la requête.
  • filter et filters créent des compartiments avec tous les documents correspondant à un ou plusieurs filtres. Cela est utile lorsque vous souhaitez restreindre davantage le jeu de documents, par exemple, pour exécuter des agrégations uniquement sur des articles en stock ou des agrégations distinctes pour ceux en stock et ceux qui sont promus.
  • missing crée un compartiment avec des documents qui n’ont pas de champ spécifié. C’est utile lorsque vous avez une autre agrégation en cours d’exécution sur un champ, mais que vous souhaitez effectuer des calculs sur des documents qui ne sont pas couverts par cette agrégation car le champ est manquant. Par exemple, vous souhaitez afficher le prix moyen des articles dans plusieurs magasins et aussi afficher le nombre de magasins ne répertoriant pas le prix de ces articles.

Global
En utilisant votre site de rencontre à partir des exemples de documents que je vous ai fournis, supposez que vous interrogez des événements sur Elasticsearch, mais que vous souhaitiez voir les balises les plus fréquentes dans l’ensemble. Par exemple, comme nous l’avons décrit précédemment, vous souhaitez afficher ces balises quelque part dans une barre latérale, indépendamment de ce que recherche l’utilisateur. Pour ce faire, vous devez utiliser l’agrégation global, qui peut modifier le flux de données d’une requête à une autre, comme illustré à la figure 7.12.

Dans la figure suivante, vous allez imbriquer l’agrégation terms dans l’agrégation global afin d’obtenir les balises les plus fréquentes sur tous les documents, même si la requête ne recherche que celles ayant «elasticsearch» dans le titre.

Lorsque nous disons «tous les documents», nous entendons tous les documents du contexte de recherche défini dans l’URI de recherche. Dans ce cas, vous effectuez une recherche dans le type groupe de l’index de rencontre, du coup tous les groupes seront pris en compte. Si vous recherchez dans tout l’index, les groupes et les événements seront inclus dans l’agrégation.

Filtre
Rappelez-vous le post-filtre (filtre de publication) de la section 7.1? Il est utilisé lorsque vous définissez un filtre directement dans la requête JSON, au lieu de le placer dans une requête filtrée. Le post-filtre limite les résultats obtenus sans affecter les agrégations.

L’agrégation filters a l’effet inverse: elle restreint le jeu de documents sur lequel vos agrégations sont exécutées sans affecter les résultats. Ceci est illustré à la figure 7.13.

Si vous recherchez des événements avec «elasticsearch» dans le titre, vous souhaitez créer un nuage de mots à partir de mots contenus dans la description, mais vous ne souhaitez comptabiliser que les documents suffisamment récents, par exemple après le 1er juillet 2013.

Pour ce faire, dans la figure suivante, vous exécuterez une requête comme d’habitude, mais avec des agrégations. Vous allez d’abord avoir une agrégation filter restreignant le jeu de documents à ceux après le 1er juillet, puis imbriquer l’agrégation terms générant les informations du nuage de mots.



Il existe également une agrégation filters (pluriel), qui vous permet de définir plusieurs filtres. Il fonctionne de la même manière que l’agrégation filter, à la différence qu’il génère plusieurs compartiments, un pour chaque filtre. De même, l’agrégation range génère plusieurs compartiments, un pour chaque plage. Pour plus d’informations sur l’agrégation filters, visitez le site www.elastic.co/guide/fr/elasticsearch/reference/current/search-aggregations-bucket-filters-aggregation.html.

Missing

La plupart des agrégations que nous avons examinées jusqu’à présent créent des compartiments de documents et obtiennent des mesures à partir des valeurs d’un champ. Si un document ne contient pas ce champ, il ne fera pas partie du compartiment et il ne contribuera à aucune métrique.

Par exemple, vous pourriez avoir une agrégation date_histogram sur des dates d’événement, mais certains événements n’ont pas encore de date définie. Vous pourrez aussi les compter à travers l’agrégation missing:

Comme pour les autres agrégations à un seul compartiment, l’agrégation missing vous permet d’imbriquer d’autres agrégations sous celle-ci. Par exemple, vous pouvez utiliser l’agrégation max pour afficher le nombre maximal de personnes souhaitant participer à un seul événement pour lequel aucune date n’a encore été définie.

Il existe d’autres agrégations importantes à un seul compartiment que nous n’avons pas abordées ici, telles que les agrégations nested et reverse_nested, qui vous permettent d’utiliser toute la puissance des agrégations avec des documents imbriqués.

L’utilisation de documents imbriqués est l’un des moyens de travailler avec des données relationnelles dans Elasticsearch. Le chapitre suivant fournit tout ce que vous devez savoir sur les relations entre les documents, y compris les documents imbriqués et les agrégations imbriquées.

7.5. RÉSUMÉ

Dans ce chapitre, nous avons présenté les principaux types d’agrégation et comment les combiner pour obtenir des informations sur les documents correspondant à une requête:

  • Les agrégations vous aident à obtenir une vue globale des résultats de la requête en comptant les termes et en calculant les statistiques à partir des documents résultants.
  • Les agrégations sont les nouvelles facettes d’Elasticsearch car il existe plus de types d’agrégations. Vous pouvez également les combiner pour obtenir des informations plus détaillées sur les données.
  • Il existe deux principaux types de colonies: paquets(buckets) et métriques.
  • Les agrégations de métriques calculent les statistiques sur un ensemble de documents, telles que la valeur minimale, maximale ou moyenne d’un champ numérique.
  • Certaines agrégations de métriques sont calculées avec des algorithmes d’approximation, ce qui leur permet de mieux s’adapter que des métriques exactes. Les agrégations  percentiles et cardinality fonctionnent comme cela.
  • Les regroupements de compartiments placent des documents dans un ou plusieurs compartiments et renvoient des compteurs pour ces compartiments, par exemple les affiches les plus fréquentes d’un forum. Vous pouvez imbriquer des sous-agrégations sous des agrégations de compartiment, ce qui permet à ces sous-agrégations d’être exécutées une fois pour chaque compartiment généré par le parent. Vous pouvez utiliser cette imbrication, par exemple, pour obtenir le nombre moyen de commentaires d’articles de blog correspondant à chaque tag.
  • L’agrégation top_hits peut être utilisée comme une sous-agrégation pour implémenter le regroupement des résultats.
  • L’agrégation terms est généralement utilisée pour les principaux utilisateurs/emplacements/éléments/…  les plus fréquents. Les autres agrégations multi-compartiments sont les variantes de l’agrégation terms, telles que l’agrégation significant_terms, qui renvoie les mots qui apparaissent plus souvent dans les résultats de la requête que dans l’index global.
  • Les agrégations range et date_range sont utiles pour catégoriser les champs numériques et les dates. Les agrégations histogram et date_histogram sont similaires, mais elles utilisent des intervalles fixes au lieu de plages définies manuellement.
  • Les agrégations à un compartiment, telles que les agrégations global, filter, et les agrégations missing, sont utilisées pour modifier le jeu de documents sur lequel d’autres agrégations sont exécutées, qui par défaut s’exécutent sur les documents renvoyés par la requête.