Chapitre 6. Le scoring

Ce chapitre couvre

  • Comment fonctionne le scoring dans Lucene et Elasticsearch
  • Booster le score d’une requête ou d’un champ en particulier
  • Compréhension de la fréquence des termes, de celle inverse des documents et des scores attribués  via l’API « Explain ».
  • Réduire l’impact du scoring en redéfinissant le score d’un sous-ensemble de documents
  • Prenez la main sur le processus de scoring en utilisant la requête function_score
  • Le cache de données au niveau des champs et leur incidence sur les instances d’Elasticsearch

De nos jours, la possibilité de faire correspondre un document à une requête est une fonctionnalité vantée par de nombreux moteurs de stockage et de recherche. Ce qui différencie réellement une requête Elasticsearch d’une requête SELECT * FROM users WHERE name LIKE ‘bob%’ est la possibilité d’attribuer une pertinence, également appelée score, à un document. A partir de ce score, vous savez quelle est la pertinence du résultat  de la recherche par rapport à la requête d’origine.

Lorsque les utilisateurs tapent une requête dans une zone de recherche d’un site Web, ils s’attendent à trouver non seulement des résultats correspondant à leur requête, mais également des résultats classés en fonction de leur pertinence avec les critères de la requête. En fait, Elasticsearch est assez flexible pour déterminer la pertinence d’un document. Il existe de nombreuses façons de personnaliser vos recherches pour obtenir des résultats plus pertinents.

Ne vous inquiétez pas si vous vous trouvez dans une position où vous ne vous souciez pas particulièrement de savoir à quel point un document correspond à une requête, mais seulement qu’il correspond ou non. Ce chapitre traite également des différentes manières de filtrer les documents. Il est important de comprendre le cache de données au niveau des champs, qui est le cache mémoire dans lequel Elasticsearch stocke les valeurs des champs des documents de l’index en matière de tri, de script , ou en agrégeant les valeurs à l’intérieur de ces champs.

Nous allons commencer le chapitre en parlant du scoring utilisé par Elasticsearch, ainsi qu’une alternative à l’algorithme de scoring par défaut, puis comment en assigner un directement à l’aide du boosting, et enfin comprendre comment le score a été calculé à l’aide de l’API Explain. Après cela, nous verrons comment réduire l’impact du scoring à l’aide de la query rescoring, ceci en étendant les requêtes pour obtenir un meilleur contrôle du scoring et en effectuant un tri personnalisé à l’aide de scripts. Enfin, nous allons parler du cache mémoire de données au niveau des champs, de la façon dont il affecte et impacte vos requêtes, ainsi que d’une alternative appelée doc_values.

Avant de voir plus en détail le concept de cache mémoire, commençons par la façon dont Elasticsearch calcule le score des documents.

6.1. COMMENT FONCTIONNE LE SCORING SUR ELASTICSEARCH

Bien qu’il soit logique de penser d’abord à la correspondance de documents à vos requêtes dans un sens binaire, c’est-à-dire «Oui, ça correspond» ou «Non, ça ne correspond pas», il est beaucoup plus logique de penser à la correspondance de documents en fonction de leur pertinence. Alors qu’avant  on se demandait plutôt si un document corresponds ou non (la méthode binaire),  aujourd’hui il est plus précis de pouvoir dire que le document A correspond mieux à une requête que le document B. Par exemple, lorsque vous effectuez notre recherche habituelle sur le mot clé “elasticsearch”, il ne suffit pas de dire qu’une page particulière contient le terme et donc corresponds; Au lieu de cela, vous souhaitez que les résultats soient classés en fonction de leur pertinence.

Le processus de détermination de la pertinence d’un document par rapport à une requête s’appelle le scoring. Bien qu’il ne soit pas nécessaire de comprendre exactement comment Elasticsearch calcule le score d’un document pour pouvoir utiliser Elasticsearch, cela reste une notion très importante à maitriser. Notamment pour les administrateurs.

6.1.1. Comment fonctionne le scoring des documents

Le scoring dans Lucene (et par extension, Elasticsearch) est une formule qui prend le document en question et utilise plusieurs éléments différents pour déterminer le score de ce document. Nous allons d’abord couvrir chaque morceau, puis les combiner dans la formule pour mieux expliquer le score global. Comme nous l’avons mentionné précédemment, nous souhaitons que les documents les plus pertinents soient renvoyés en premier. Dans Lucene et Elasticsearch, cette pertinence est appelée le score.

Pour commencer à calculer le score, Elasticsearch utilise la fréquence du terme recherché, ainsi que sa fréquence d’utilisation dans d’autre documents. Une brève explication est que plus un terme est utilisé dans un document, plus il est pertinent. Mais plus le terme apparaît dans tous les documents, moins ce terme est pertinent. Ceci s’appelle TF-IDF (TF = fréquence des termes, IDF = fréquence de document inverse), et nous allons maintenant parler de chacun de ces types de fréquence de manière plus détaillée.

6.1.2. Fréquence des termes

La première façon de penser au scoring d’un document consiste à déterminer la fréquence à laquelle un terme apparaît dans le texte. Par exemple, si vous recherchiez des réunions autour d’Elasticsearch dans votre région, vous voudriez que les groupes qui mentionnent Elasticsearch plus fréquemment apparaissent en premier. Prenez en compte les extraits de texte suivants, illustrés à la figure 6.1.

La première phrase mentionne Elasticsearch une seule fois et la seconde mentionne Elasticsearch deux fois. Par conséquent, le document contenant la deuxième phrase doit avoir un score supérieur à celui d’un document contenant la première. Si nous devions parler en chiffres absolus, la première phrase aurait une fréquence de termes de 1 (TF) et la seconde phrase aurait une fréquence de termes 2 .

6.1.3. Fréquence de document inverse

La fréquence de document inverse (IDF) est légèrement plus compliquée que la fréquence des termes pour un document. Cette description aux allures fantaisistes signifie qu’un jeton (généralement un mot, mais pas toujours) est moins important à mesure qu’il survient dans tous les documents de l’index. Ceci est plus facile à expliquer avec quelques exemples. Considérons les trois documents illustrés à la figure 6.2.

Dans les trois documents de la figure, notez ce qui suit:

  • Le terme «Elasticsearch» a une fréquence de documents de 2 (car il apparaît dans deux documents). La partie « inverse » de la fréquence de document provient du fait que le score est multiplié par 1 / DF, DF étant la fréquence de document du terme. Cela signifie que, comme le terme a une fréquence de document plus élevée, son poids diminue.
  • Le terme «the» a une fréquence de document de 3 car il apparaît dans les trois documents. Notez que la fréquence de «the» est toujours 3, même si «the» apparaît deux fois dans le dernier document, car la fréquence inverse de document ne vérifie que la présence d’un terme dans le document et non la fréquence à laquelle il apparaît dans le document. C’est le travail de la fréquence des termes!

La fréquence de document inverse est un facteur important pour équilibrer la fréquence d’un terme. Par exemple, considérons un utilisateur qui recherche le terme «the score»; le mot the est susceptible de figurer dans presque tous les textes anglais normaux. Par conséquent, s’il n’était pas équilibré, sa fréquence dépasserait totalement celle du mot « score ». La IDF équilibre l’impact de la pertinence de mots courants tels que « the », de sorte que le score de pertinence réel donne une idée plus précise des termes de la requête.

Une fois que le TF et l’IDF ont été calculés, vous êtes prêt à calculer le score d’un document à l’aide de la formule TF-IDF.

6.1.4. La formule de scoring de Lucene

La formule de scoring par défaut de Lucene, connue sous le nom de TF-IDF, décrite dans la section précédente, est basée à la fois sur la fréquence des termes et sur la fréquence de document inverse d’un terme. Examinons d’abord la formule, illustrée à la figure 6.3, puis nous aborderons chaque partie individuellement.

En lisant ceci en language humain, nous dirions: «Le score pour une requête donnée q et le document d est la somme (pour chaque terme t de la requête) de la racine carrée de la fréquence du terme dans le document d, multiplié par la fréquence inverse du document du terme au carré, multipliée par le facteur de normalisation du champ dans le document, multipliée par le boost du terme. ”

Ouf, c’était une bouchée à lire! Ne vous inquiétez pas vous n’avez pas besoin de mémoriser cette formule pour utiliser Elasticsearch. Nous le fournissons ici pour que vous puissiez comprendre comment le score est calculée. L’important est de comprendre comment la fréquence des termes et la fréquence inverse d’un document sur le document affectent le score du document et en quoi elles sont essentielles à la détermination du score d’un document dans un index Elasticsearch.

Plus la fréquence des termes est élevée, plus le score est élevé; de même, plus la fréquence du document est rare, plus la fréquence de document inverse est élevée. Bien que nous ayons maintenant fini avec TF-IDF, nous n’en avons pas fini avec la fonction de scoring par défaut de Lucene. Il manque deux choses: le facteur de coordination et la query de normalisation. Le facteur de coordination prend en compte le nombre de documents recherchés et le nombre de termes trouvés. La norme de requête est une tentative pour rendre les résultats des requêtes comparables. Il s’est avèré que cela est difficile et qu’en réalité, vous ne devez pas comparer les scores des différentes requêtes. Cette méthode d’évaluation du score par défaut est une combinaison du modèle TF-IDF et du modèle d’espace vectoriel.

Si vous souhaitez en savoir plus à ce sujet, nous vous recommandons de consulter les Javadocs pour la classe Java org.apache.lucene.search.similarities.TFIDFSimilarity dans la documentation de Lucene.

6.2. AUTRES METHODES DE SCORING

Bien que le modèle de scoring de la section précédente, une combinaison de TF-IDF et du modèle d’espace vectoriel, soit sans doute le mécanisme de scoring le plus populaire pour Elasticsearch et Lucene, cela ne veut pas dire que c’est le seul modèle. Il en existe d’autres:

  • Okapi BM25
  • Divergence de l’aléatoire ou similitude DFR
  • Basé sur l’information, ou la similarité IB
  • Similarité de LM Dirichlet
  • Similarité de LM Jelinek Mercer

Nous aborderons brièvement l’une des alternatives les plus populaires ici (BM25) et expliquons comment configurer Elasticsearch pour l’utiliser. Lorsque nous parlons de méthodes de scoring, nous parlons de changer le module de similarité dans Elasticsearch.

Avant de parler de la méthode de scoring alternative à TF-IDF (connue sous le nom de BM25, un système de scoring probabiliste), voyons comment configurer Elasticsearch pour l’utiliser. Il existe deux manières différentes de spécifier la similarité d’un champ. La première consiste à modifier le paramètre de similarité dans le mapping d’un champ, comme indiqué dans la figure suivante.

La deuxième façon de configurer Elasticsearch pour qu’elle utilise une autre méthode de scoring consiste à le spécifier dans le mapping du champ. La similarité est définie dans les paramètres, de la même manière que l’analyseur, puis référencée dans le mapping d’un champ par son nom. Cette approche vous permet de configurer les paramètres d’un algorithme de similarité. La figure suivante montre un exemple de configuration de paramètres avancés pour la similarité BM25 et d’utilisation de cet algorithme de scoring pour un champ dans le mapping.

De plus, si vous avez décidé de toujours utiliser une méthode de scoring particulière, vous pouvez la configurer globalement en ajoutant le paramètre suivant à votre fichier de configuration elasticsearch.yml:

Génial! Maintenant que vous avez compris comment spécifier une similarité alternative, examinons là et voyons ses différences avec TF-IDF.

6.2.1. Okapi BM25

Okapi BM25 est probablement la deuxième méthode de scoring la plus utilisée après TF-IDF pour Lucene et constitue un algorithme de pertinence probabiliste, ce qui signifie que le score peut être considéré comme la probabilité qu’un document donné corresponde à la requête. BM25 est également réputé être meilleur pour les champs plus courts, bien que vous devriez toujours tester pour vous assurer qu’il reste vrai pour votre jeu de données! Le BM25 mappe chaque document dans un tableau de valeurs correspondant à chaque terme du dictionnaire et utilise un modèle probabiliste pour déterminer le classement du document.

Bien que discuter de la formule de notation complète du BM25 dépasse le cadre de ce livre, vous pouvez en savoir plus sur la mise en œuvre du BM25 dans Lucene à l’adresse http://arxiv.org/pdf/0911.5046.pdf.

Le BM25 a trois paramètres principaux: k1, b et discount_overlaps:

  • k1 et b sont des paramètres numériques utilisés pour modifier le calcul du score.
  • k1 contrôle l’importance de la fréquence des termes dans le score (fréquence à laquelle le terme apparaît dans le document:TF).
  • b est un nombre compris entre 0 et 1 qui contrôle le degré d’impact de la longueur du document sur le score.
  • k1 est défini sur 1,2 et b est défini sur 0,75 par défaut.
  • Le paramètre discount_overlaps peut être utilisé pour indiquer à Elasticsearch que plusieurs jetons apparaissant au même emplacement dans un champ doivent ou non avoir une incidence sur la normalisation de la longueur. La valeur par défaut est true.


Tester votre score

N’oubliez pas que si vous modifiez ces paramètres, vous devez vous assurer de disposer d’une bonne infrastructure de test avec laquelle vous pourrez évaluer les modifications apportées au classement et au scoring de vos documents. Cela n’a aucun sens de modifier les paramètres de l’algorithme de pertinence sans disposer d’un moyen d’évaluer vos modifications de manière reproductible; Si ce n’est pas le cas, tout ce que vous faite c’est juste deviner!



Maintenant que vous avez vu la formule de notation TF-IDF par défaut ainsi qu’une alternative, BM25, voyons comment vous pouvez influencer le scoring des documents de manière plus fine, avec le boost.

6.3. Boosting

Le boosting est le processus par lequel vous pouvez modifier la pertinence d’un document. Il existe deux types de boosting. Vous pouvez améliorer un document pendant que vous l’indexez ou lorsque vous interrogez le document. Étant donné que booster un document au moment de l’indexation stocke les données dans l’index, et que le seul moyen de modifier cette valeur de boost est de réindexer le document, nous vous recommandons vivement de booster vos documents lors de vos requêtes. Vous aurez plus de flexibilité et pourrez changer d’avis sur les champs ou les termes importants sans avoir à réindexer vos données.

Prenons l’exemple de l’index get-together. Dans cet exemple, si vous recherchez un groupe, il est logique de faire en sorte le titre d’un groupe soit plus important que la description du groupe. Prenez le groupe Elasticsearch Berlin. Le titre ne contient que les informations les plus importantes sur lesquelles le groupe se concentre, Elasticsearch dans la région de Berlin, par opposition à la description du groupe, qui peut contenir beaucoup plus de termes. Le titre d’un groupe doit donc avoir plus de poids que la description et, pour ce faire, vous utiliserez le boosting.

Avant de commencer, cependant, il est important de mentionner que les nombres utilisés pour booster ne sont pas des multiplicateurs exacts. Cela signifie que la valeur de boost est normalisée lors du calcul des scores. Par exemple, si vous spécifiez un boost de 10 pour chaque champ, le résultat sera normalisé à 1 pour chaque champ, ce qui signifie qu’aucun boost n’est appliquée. Vous devriez penser aux nombres utilisés pour le boosting comme relatifs; Booster de 3 le champ name signifie que le champ name est environ trois fois plus important que les autres champs.

6.3.1. Le Boosting à l’indexation

Comme nous l’avons mentionné, en plus d’améliorer le score d’un document lors d’une requête, vous pouvez également le renforcer au moment de l’indexation. Même si nous ne recommandons pas cette façon de booster, comme vous le verrez bientôt, elle peut toujours être utile dans certains cas, alors parlons un peu de la façon de le faire.

Lorsque vous effectuez ce type de boosting, vous devez spécifier le mapping de votre champ avec le paramètre boost. Par exemple, pour renforcer le champ name du groupe, vous devez créer un index avec un mapping qui ressemble à celui de la figure suivante.

Après avoir spécifié ce mapping pour l’index, tous les documents indexés automatiquement bénéficient d’une surélévation appliquée aux termes du champ name (stocké avec le document dans l’index Lucene). De nouveau, rappelez-vous que cette valeur de boost est fixe, ce qui signifie que si vous décidez de la modifier, vous devrez réindexer les données.

Une autre raison de ne pas booster au moment de l’indexation est que les valeurs de boost sont stockées en tant que valeurs de faible précision dans la structure d’index interne de Lucene; seulement un seul octet est utilisé pour stocker la valeur du boost à virgule flottante. Il est donc possible de perdre de la précision lors du calcul du score final d’un document.

La dernière raison est que le boost est appliqué à tous les termes. Par conséquent, la mise en correspondance de plusieurs termes dans le champ boosté implique un boost multiplié, augmentant encore plus le poids pour le champ.

En raison de ces problèmes liés au boosting au moment de l’indexation, il est vivement recommandé de le faire lors de l’exécution des requêtes, comme vous le verrez ensuite.

6.3.2. Boosting au moment de la requête

Il y a pas mal de façons de dynamiser votre recherche. Si vous utilisez les requêtes de base match, multi_match, simple_query_string ou query_string, vous contrôlez le boost par terme ou par champ. Presque tous les types de requêtes Elasticsearch prennent en charge le boosting. Si elles ne sont pas assez flexible, vous pouvez contrôler le boosting de manière encore plus fine avec la requête function_score, que nous traiterons un peu plus loin dans ce chapitre.

Avec la query match, vous pouvez booster la requête en utilisant le paramètre supplémentaire boost, comme indiqué dans la figure suivante. Lorsque vous booster la requête, cela signifie que chaque terme trouvé dans le champ configuré pour lequel vous effectuez la requête reçoit un boost.

Cela fonctionne également pour d’autres requêtes fournies par Elasticsearch, telles que la query term, la query prefixe, etc. Dans l’exemple précédent, notez qu’un boost a été ajouté uniquement à la première query match. Désormais, la première query a un impact plus important sur le score final que la seconde. Il n’est utile d’intensifier une requête que lorsque vous combinez plusieurs requêtes à l’aide des query bool or/ and/ not.

6.3.3. Requêtes couvrant plusieurs champs

Pour les requêtes portant sur plusieurs champs, telles que la query multi_match, vous avez également accès à une autre syntaxe. Vous pouvez spécifier l’amplification de l’ensemble multi_match, similaire à la query match avec le paramètre boost que vous avez déjà vu, comme indiqué dans la figure suivante:

Ou vous pouvez spécifier un boost pour des champs particuliers uniquement en utilisant une syntaxe spéciale. En ajoutant le nom du champ avec un caret (^) et la valeur de boost, vous indiquez à Elasticsearch de ne booster que ce champ. La figure suivante montre un exemple de la requête précédente, mais au lieu de booster la totalité de la requête, vous booster uniquement le champ du nom.

Dans la query query_string, vous pouvez renforcer des termes individuels à l’aide d’une syntaxe spéciale, en ajoutant au terme un signe d’insertion (^) et la valeur de boost. Un exemple de recherche pour “elasticsearch” et “big data” et booster “elasticsearch” de 3 ressemblerait à la figure suivante.

Comme nous l’avons déjà mentionné, gardez à l’esprit, lorsqu’il s’agit de booster des champs ou des termes, qu’un boost est une valeur relative et non un multiplicateur absolu. Si vous augmentez de la même quantité tous les termes que vous recherchez, c’est comme si vous ne les accentuiez pas, car Lucene normalise les valeurs de boost. N’oubliez pas que le fait de booster un champ de 4 ne signifie pas automatiquement que le score de ce champ sera multiplié par 4, alors ne vous inquiétez pas si le score n’est pas une multiplication exacte.

Vu que le boosting au moment de la requête est plus flexible, ne vous en privez pas! N’ayez pas peur de jouer avec l’ensemble de vos données jusqu’à ce que vous obteniez la pertinence souhaitée pour vos résultats. Changer le boosting est aussi simple que d’ajuster un nombre dans la requête que vous envoyez à Elasticsearch.

6.4. COMPRENDRE COMMENT UN DOCUMENT A ÉTÉ SCORÉ AVEC EXPLAIN

Avant d’aller beaucoup plus loin dans la personnalisation du scoring des documents, nous devons expliquer comment décomposer la score d’un document en fonction du resultat obtenu, avec les chiffres réels que Lucene utilise sous le capot. Ceci est utile pour comprendre pourquoi un document correspond mieux à une requête qu’un autre du point de vue d’Elasticsearch.

Il s’agit ici ni plus ni moins que d’expliquer le score. Vous pouvez demander à Elasticsearch de le faire en spécifiant l’indicateur explain = true, soit sur l’URL lors de l’envoi de la demande, soit en définissant l’indicateur explain sur true dans le corps même de la requête. Cela peut être utile pour expliquer pourquoi un document a été évalué d’une manière particulière, mais cela a un autre usage: expliquer pourquoi un document ne correspond pas à une requête. Cela s’avère utile si vous vous attendez à ce qu’un document corresponde à une requête mais qu’il ne soit pas renvoyé dans les résultats.

Avant d’y arriver, voyons un exemple d’explication de résultat d’une requête dans la figue suivante.

Vous pouvez voir dans cette figure comment ajouter le paramètre explain. Ceci, à son tour, produit une sortie plutôt verbeuse. Jetons un coup d’œil au premier résultat renvoyé par cette requête:

La partie ajoutée de cette réponse est la nouvelle clé _explanation, qui contient une ventilation de chacune des différentes parties du score. Dans ce cas, vous recherchez «elasticsearch» dans la description et le terme «elasticsearch» apparaît une fois dans la description du document. La fréquence de terme (TF) ici est donc de 1.

De même, l’explication de fréquence de document inverse (IDF) montre que le terme «elasticsearch» apparaît dans 6 des 12 documents de cet index. Enfin, vous pouvez également voir la normalisation de ce champ, que Lucene utilise en interne. Ces scores multipliés ensemble déterminent le score final:

N’oubliez pas qu’il ne s’agit que d’un exemple simple avec un seul terme de requête et que nous n’avons examiné que l’explication d’un document unique. L’explication peut être extrêmement verbeuse et beaucoup plus difficile à comprendre lorsqu’elle est utilisée pour des requêtes plus complexes. Il est également important de mentionner que l’utilisation de la fonction Explain ajoute une charge supplémentaire à Elasticsearch lors de l’interrogation. Assurez-vous de l’utiliser uniquement pour déboguer une requête, plutôt que de la spécifier par défaut à chaque requête.

6.4.1. Expliquer pourquoi un document ne correspond pas

Nous avons mentionné plus tôt que la fonction explain a une autre utilisation. Tout comme vous pouvez obtenir une explication sur la manière dont le score a été calculé pour un document particulier, vous pouvez également utiliser l’API explain pour expliquer pourquoi un document ne correspond pas à une requête.

Mais dans ce cas, étant donné que vous ne pouvez pas simplement ajouter le paramètre explain, il faudra utiliser une autre API, comme indiqué dans la figure suivante.

Dans cet exemple, étant donné que le terme «elasticsearch» ne figure pas dans le champ de description de ce document, l’explication est un simple «pas de terme correspondant». Vous pouvez également utiliser cette API pour obtenir le score d’un seul document si vous connaissez l’identifiant du document.

Armé de cet outil, qui vous permet de déterminer comment les documents sont évalués, n’hésitez pas à l’expérimenter. Amusez vous. N’ayez pas peur d’utiliser les outils de ce livre pour modifier votre score.

Ensuite, avant de parler plus en détail de la modification du score, nous allons parler de l’impact du scoring et de ce que vous pouvez faire si vous trouvez que le scoring prend trop de temps.

6.5. RÉDUCTION DE L’IMPACT DU SCORIN AVEC LA QUERY RESCORING

Quelque chose dont nous n’avons pas encore parlé est l’impact du scoring sur la vitesse du système. Dans la plupart des requêtes habituelles, le calcul du score d’un document nécessite juste un léger surcoût. Ceci est dû au fait que TF-IDF a été fortement optimisé par l’équipe Lucene pour être efficace.

Dans certains cas, cependant, le scoring peut nécessiter plus de ressources:

  • Lors du scoring avec un script exécuté pour calculer le score de chaque document dans l’index
  • Lorsque vous effectuer une requête avec la query phrase qui va rechercher les mots situés à une certaine distance les uns des autres, avec un grand slop (voir section 4.2.1).

Dans ces cas, vous souhaiterez peut-être réduire l’impact de l’algorithme de scoring exécuté sur des millions ou des milliards de documents.

Pour remédier à cela, Elasticsearch dispose d’une fonctionnalité appelée Rescoring. Le Rescoring signifie qu’une requête initiale est effectuée, puis un deuxième round de scoring est effectué sur les résultats renvoyés. d’où le nom. Cela signifie que pour une requête potentiellement coûteuse utilisant un script, vous ne pouvez l’exécuter que sur les 1 000 occurrences les plus importantes extraites, à l’aide d’une query match beaucoup moins lourde. Voyons un exemple d’utilisation du rescoring dans la figure suivante.

Dans cet exemple, vous recherchez tous les documents ayant le titre «elasticsearch» dans le titre, puis prenez les 20 meilleurs résultats et effectuez une nouvelle analyse, en utilisant une query phrase avec un niveau de slop élevé. Même si une query phrase avec une valeur de slop élevée peut être coûteuse à exécuter, vous n’avez pas à vous inquiéter, car la requête ne fonctionnera que sur les 20 documents les plus importants au lieu de millions ou de milliards de documents. Vous pouvez utiliser les paramètres query_weight et rescore_query_weight pour pondérer chacune des différentes requêtes, en fonction du degré de détermination du score par la requête initiale et la query rescore. Vous pouvez utiliser plusieurs requêtes de rescore en séquence, chacune prenant la précédente en entrée.

6.6. SCORING PERSONNALISÉ AVEC LA FUNCTION_SCORE

Enfin, nous arrivons à l’une des requêtes les plus intéressantes proposées par Elasticsearch: function_score. La requête function_score vous permet de contrôler de manière précise la pertinence de vos résultats en spécifiant un nombre quelconque de fonctions arbitraires à appliquer au score des documents correspondant à une requête initiale.

Dans ce cas, chaque fonction est un petit extrait de code JSON qui influence d’une manière ou d’une autre le score. Cela semble déroutant? Eh bien, nous allons éclaircir la question à la fin de cette section. Nous allons commencer par la structure de base de la query function_score; la figure suivante est un exemple qui effectue un scoring plutôt simple.

Assez simple: cela ressemble à une query match normale dans un wrapper function_score. Une nouvelle clé,  functions, qui est actuellement vide pour le moment. Vous allez mettre des choses dans ce tableau dans quelsques secondes. Cette figure est destinée à montrer que les résultats de cette requête seront les documents sur lesquels les fonctions function_score opèrent. Par exemple, si vous avez 30 documents au total dans l’index et que la query match pour le terme «elasticsearch» dans le champ description correspond à 25 d’entre eux, les fonctions à l’intérieur du tableau seront appliquées à ces 25 documents.

La query function_score a un certain nombre de fonctions différentes et, en plus de la requête d’origine, chaque fonction peut prendre un filtre différent. Vous en verrez des exemples à mesure que nous détaillerons chaque fonction dans les sections suivantes.

6.6.1. Le poids

La fonction weight est la plus simple du groupe; il multiplie le score par un nombre constant. Notez qu’au lieu d’un boost normal, qui augmente le score d’une valeur normalisée, le poids multiplie réellement le score par la valeur.

Dans l’exemple précédent, vous aviez déjà recupéré tous les documents contenant le terme «elasticsearch» dans la description. Vous pouvez donc booster les documents contenant «hadoop» dans la description.

La seule modification apportée à l’exemple consistait à ajouter l’extrait de code suivant au tableau de fonctions:

Cela signifie que le score des documents contenant le terme « hadoop » dans la description sera multiplié par 1,5.

Vous pouvez en avoir autant que vous le souhaitez. Par exemple, pour booster également le score des groupes de rendez-vous qui mentionnent «logstash», vous pouvez spécifier deux fonctions weight différentes, comme dans la figure suivante.

6.6.2. Combinaison des scores

Parlons de la manière dont ces scores sont combinés. Nous devons discuter de deux facteurs lorsque nous parlons de scores:

  • Comment les scores de chacune des fonctions doivent être combinés, appelé score_mode
  • Comment combiner le score des fonctions avec le score de la requête d’origine (recherche de «elasticsearch» dans le champ description de notre exemple), appelé boost_mode

Le premier facteur, appelé paramètre score_mode, concerne la manière dont les scores de chacune des différentes fonctions sont combinés. Dans la précédente requête cURL, vous avez deux fonctions: l’une avec un poids de 2, l’autre avec un poids de 3. Vous pouvez définir le paramètre score_mode sur multiplysumavgfirstmax, or min. Si non spécifié, les scores de chaque fonction seront multipliés ensemble tout simplement.

Si first est spécifié, seule la première fonction avec un filtre correspondant aura son score pris en compte. Par exemple, si vous définissez score_mode sur first et que vous avez un document contenant à la fois «hadoop» et «logstash» dans la description, seul un facteur de boost de 2 sera appliqué, car c’est la première fonction qui correspond au document.

Le second paramètre de combinaison de score, appelé boost_mode, contrôle la manière dont le score de la requête d’origine est combiné aux scores des fonctions elles-mêmes. S’il n’est pas spécifié, le nouveau score sera le score de la requête d’origine multiplié par le score de la fonction combinée. Vous pouvez changer cela en sumavgmaxmin, or replace. Lorsque cette option est sur replace, le score de la requête d’origine est remplacé par le score des fonctions.

Les fonctions que nous couvrirons sont field_value_factor, script_score et random_score, ainsi que les trois fonctions de decay: linear, gauss et exp. Nous allons commencer par la fonction field_value_factor.

6.6.3. field_value_factor

Modifier le score en fonction d’autres requêtes est très utile, mais beaucoup de personnes souhaitent utiliser les données contenues dans leurs documents pour influencer le score d’un document. Dans cet exemple, vous pouvez utiliser le nombre d’avis qu’un événement a reçus pour augmenter le score de cet événement. cela est possible en utilisant la fonction field_value_factor dans une query function_score.

La fonction field_value_factor prend le nom d’un champ contenant un champ numérique, le multiplie éventuellement par un nombre constant, puis applique enfin une fonction mathématique telle que prendre le logarithme de la valeur. Regardez l’exemple dans la figure suivante.

Le score qui sort de la fonction field_value_factor ici sera:

Pour un document avec une valeur de 7 dans le champ commentaires, le score serait:

Outre ln, il existe d’autres modificateurs: none(par défaut), log, log1p, log2p, ln1p, ln2p, square, sqrt et reciprocal. Une dernière chose à retenir lorsque vous utilisez field_ value_factor: il charge toutes les valeurs du champ que vous avez spécifié en mémoire afin que les scores puissent être calculés rapidement. Maintenant nous allons couvrir une autre fonction, qui peut vous donner un contrôle plus fin sur l’influence sur le score en spécifiant un script personnalisé.

6.6.4. Script

Le scoring par script vous donne le contrôle complet sur la façon de changer le score. Vous pouvez effectuer n’importe quel type de scoring dans un script.

Pour un bref rappel, les scripts sont écrits dans la langue Groovy et vous pouvez accéder au score originale du document en utilisant _score dans un script. Vous pouvez accéder aux valeurs d’un document en utilisant doc [‘fieldname’]. Un exemple de scoring utilisant un script légèrement plus complexe est présenté dans la figure suivante.

Dans cet exemple, vous utilisez la taille de la liste des participants pour influencer le score en le multipliant par un poids et en en prenant le logarithme.

Les scripts sont extrêmement puissants car vous pouvez faire tout ce que vous voulez à l’intérieur, mais gardez à l’esprit que les scripts seront beaucoup plus lents que le scoring habituel, car ils doivent être exécutés de manière dynamique pour chaque document correspondant à votre requête. Lorsque vous utilisez le script paramétré comme dans la figure 6.15, la mise en cache du script améliore les performances.

6.6.5. Random

La fonction random_score vous permet d’attribuer des scores aléatoires à vos documents. L’avantage de pouvoir trier les documents de manière aléatoire est la possibilité d’introduire un peu de variation dans la première page de résultats. Lors de la recherche de groupes de rencontres, il est parfois agréable de ne pas toujours voir le même résultat au sommet.

Vous pouvez également éventuellement spécifier une valeur de départ(seed), qui est un nombre passé avec la requête qui sera utilisée pour générer le caractère aléatoire de la fonction; Cela vous permet de trier les documents de manière aléatoire, mais en utilisant le même paramètre de départ, les résultats seront triés de la même manière si la même demande est exécutée à nouveau. C’est la seule option prise en charge, ce qui en fait une fonction simple.

La figure suivante montre un exemple d’utilisation de cette méthode pour trier des réunions au hasard.

Ne vous inquiétez pas si cela ne vous semble pas encore utile. Une fois que nous aurons couvert toutes les fonctions, nous trouverons un exemple qui les liera toutes ensemble à la fin de cette section. Avant de faire cela, cependant, il y a un autre ensemble de fonctions dont nous devons discuter: les fonctions de déclin (decay functions).

6.6.6. Fonctions de déclin(decay)

Le dernier ensemble de fonctions pour function_score sont des fonctions de déclin. Ils vous permettent d’appliquer une décroissance progressive du score d’un document en fonction de certains champs. Cela peut être utile de plusieurs manières. Par exemple, vous voudrez peut-être que les rencontres les plus récentes aient un score plus élevé, le score diminuant progressivement à mesure que les rencontres prennent de l’âge. Un autre exemple concerne les données de géolocalisation; En utilisant les fonctions de déclin, vous pouvez augmenter le score des résultats plus proches d’un point géographique (l’emplacement de l’utilisateur, par exemple) et le diminuer d’autant plus le groupe est éloigné du point.

Il existe trois types de fonctions de déclin: linéaire, gauss et exp. Chaque fonction de déclin suit le même type de syntaxe:

Le TYPE peut être l’un des trois types. Chacun des types correspond à une courbe de forme différente, illustrée aux figures 6.4, 6.5 et 6.6.

6.6.7. Options de configuration

Les options de configuration définissent l’apparence de la courbe. Il existe quatre options de configuration pour chacune des trois courbes de décroissance(déclin, decay):

  • L’origine est le point central de la courbe, c’est donc le point où vous souhaitez que le score soit le plus élevé. Dans l’exemple de géo-distance, l’origine traduit très souvent l’emplacement actuel d’une personne. Dans d’autres situations, l’origine peut également être une date ou un champ numérique.
  • L’offset est la distance avec le point d’origine, avant que le score commence à être réduit. Dans notre exemple, si l’offset est défini sur 1 km, cela signifie que le score ne sera pas réduit pour les points situés à moins d’un kilomètre du point d’origine. La valeur par défaut est 0, ce qui signifie que le score commence immédiatement à se dégrader lorsque la valeur numérique s’éloigne de l’origine.
  • Les options scale et decay vont de pair; en les définissant, vous pouvez dire qu’à la valeur scale pour un champ, le score doit être réduit à la valeur decay. Cela semble déroutant? C’est beaucoup plus simple d’y penser avec les valeurs réelles. Si vous définissez le paramètre scale à 5 km et decay sur 0,25, c’est la même chose que si vous dites «à 5 km de mon point d’origine, le score doit être 0,25 fois le score à l’origine».

La figure suivante montre un exemple de déclin gaussien du score avec les données de notre index get-together.

Voyons ce qui se passe dans cette figure:

  • Vous utilisez une requête match_all, qui renverra tous les résultats.
  • Ensuite, vous evaluez le score en utilisant une décroissance gaussienne sur le score.
  • Le point d’origine se situe à Boulder, dans le Colorado. Parmis les résultats obtenus, les groupes get-together situés à Boulder, sont ceux qui auront obtenu les meilleurs score, puis ceux de Denver (une ville proche de Boulder), et ainsi de suite, à mesure que les rencontres se déroulent plus loin du point d’origine, le score diminuera.

6.7. VUE D’ENSEMBLE DES DERNIERS CONCEPTS

Nous avions promis de montrer un exemple utilisant plusieurs fonctions. Chose promise, chose due. La figure suivante montre une requête pour tous les événements de get-together, où

  • Un terme particulier est plus pondéré que les autres.
  • Les avis sont pris en compte.
  • Les événements avec plus de participants ont un score plus élevé.
  • Les événements plus proches d’un point géographique sont boostés.

Voir l’exemple aura plus de sens, alors jetez un coup d’œil à la figure suivante.

Dans cet exemple, les événements suivants se produisent:

 

1. Vous commencez par faire correspondre tous les événements de l’index avec la query match_all.

2. Vous boostez ensuite les événements qui ont le terme «hadoop» dans le champ description à l’aide de la fonction weight.

3. Ensuite, vous utilisez le nombre d’avis qu’un événement a reçus pour modifier le score à l’aide de la fonction field_value_factor.

4. Ensuite, vous prenez en compte le nombre de participants à l’aide de script_score.

5. Enfin, vous faites décroître graduellement le score au fur et à mesure qu’il s’éloigne de votre point d’origine avec la décomposition de Gauss.

6.8. TRIAGE AVEC SCRIPTS

En plus de modifier le score d’un document avec un script, Elasticsearch vous permet d’utiliser un script pour trier les documents avant qu’ils ne vous soient renvoyés. Cela peut être utile si vous devez trier sur un champ qui n’existe pas en tant que champ dans le document.

Par exemple, imaginons que vous recherchiez des événements sur «elasticsearch» mais que vous souhaitiez trier les groupes en fonction du nombre de personnes présentes; vous pouvez facilement le faire avec la requête indiquée dans la figure suivante.

Vous remarquerez que vous retrouverez dans chaque document correspondant un champ qui ressemble à « sort »: [5.0, 0.28856182]; Ce sont les valeurs utilisées par Elasticsearch pour trier les documents. Notez que le 5.0 est un nombre; c’est parce que vous avez spécifié à Elasticsearch que la sortie de votre script était un nombre (par opposition à une chaîne). La deuxième valeur du tableau de tri est le score d’origine du document, car vous l’avez spécifiée comme champ de tri suivant, au cas où le nombre de participants correspondrait pour plusieurs documents.

Bien que cela soit puissant, il est beaucoup plus facile et rapide d’utiliser plutôt la query function _score pour influencer le score de votre document et trier par _score au lieu de trier à l’aide d’un script personnalisé; De cette façon, tous vos changements sur la pertinence se font à un seul endroit (la requête) et non à l’intérieur du tri.

Une autre option consiste à définir le nombre de participants dans un autre champ numérique du document indexé. Cela facilite le tri ou le changement du score à l’aide d’une fonction.

Faisons ensuite un petit détour et parlons de quelque chose qui est quelque peu lié au script mais qui est un peu différent d’une certaine mannière: field data

6.9. FIELD DATA (Données de champs)

L’index inversé est idéal lorsque vous souhaitez rechercher un terme et récupérer les documents correspondants. Toutefois, lorsque vous devez trier un champ ou renvoyer des agrégations, Elasticsearch doit déterminer rapidement, pour chaque document correspondant, les termes qui seront utilisés pour le tri ou les agrégations.

Les index inversés ne fonctionnent pas bien pour ce type de tâches, et c’est là que les données de champs(field data) deviennent utiles. Lorsque nous parlons de données de champs, nous parlons de toutes les valeurs uniques d’un champ. Elasticsearch charge ces valeurs en mémoire. Si vous avez trois documents qui ressemblent à ceux-ci:

les termes qui seraient chargés en mémoire seraient quickbrownfoxslow, et turtle. Elasticsearch les charge de manière compressée dans le cache de données de champ, que nous examinerons ensuite.

6.9.1. Le cache de données de champs

Le cache de données de champ est un cache en mémoire qu’Elasticsearch utilise pour un certain nombre de choses. Ce cache est généralement (mais pas toujours) construit la première fois que les données sont nécessaires, puis conservé pour être utilisé pour diverses opérations. Ce chargement peut prendre beaucoup de temps et de CPU si vous avez beaucoup de données, ce qui ralentit votre première recherche.

C’est là que les warmers, les requêtes exécutées automatiquement par Elasticsearch pour s’assurer que les caches internes sont remplis, peuvent être utiles pour précharger les données utilisées pour les requêtes avant qu’elles ne soient nécessaires. Nous discuterons plus longuement des warmers au chapitre 10.



Pourquoi le cache de données de champ est si nécessaire ?
Elasticsearch a besoin de ce cache car de nombreuses opérations de comparaison et d’analyse s’effectue sur une grande quantité de données. La seule façon de réaliser ces opérations dans un délai raisonnable est si les données sont accessibles en mémoire. Elasticsearch fait de son mieux pour minimiser la quantité de mémoire occupée par ce cache, mais il reste l’un des plus gros utilisateurs d’espace de mémoire par la jvm.



Vous devez non seulement connaître la mémoire utilisée par le cache, mais également être conscient du fait que le chargement initial de ce cache puisse prendre un certain temps. Vous remarquerez peut-être cela lorsque vous effectuez des agrégations et constatez que la première agrégation prend 2 à 3 secondes, tandis que les demandes d’agrégation suivantes sont renvoyées dans un délai de 30 millisecondes.

Si ce temps de chargement devient problématique, vous pouvez renvoyer la charge au moment de l’index et faire en sorte qu’Elasticsearch charge automatiquement les données du champ lors de la mise à disposition d’un nouveau segment. Pour le faire, pour un champs  sur lequel vous devrez trier ou faire une aggrégation, vous devez spécifier le champs fielddata.loading  sur eager dans le mapping. Dans ce cas, Elasticsearch n’attendra plus la première recherche pour charger les données de champ, mais le fera dès qu’elles seront disponibles pour le chargement (Juste après l’indexation).

Voici un exemple dans la figure suivante.

6.9.2. A quoi servent les field data

Comme mentionné précédemment, les données de champ (field data) sont utilisées pour un certain nombre d’éléments dans Elasticsearch. Voici quelques utilisations :

  • Tri par champ
  • Agrégation sur un champ
  • Accéder à la valeur d’un champ dans un script avec la notation doc [fieldname‘]
  • Utilisation de la fonction field_value_factor dans la query function_score
  • Utilisation des fonctions de déclin dans la query function_score
  • Renvoi de champs à partir de données de champ à l’aide de fielddata_fields dans une requête de recherche
  • Mettre en cache les identifiants d’une relation de documents parent/enfant

Le plus courant de ces usages est probablement le tri ou l’agrégation sur un champ. Par exemple, si vous triez les résultats des groupes de rencontre en fonction du champ organizer, toutes les valeurs uniques de ce champ doivent être chargées en mémoire pour pouvoir être comparées efficacement afin de fournir un ordre de tri.

Juste après le tri sur un champ, l’agrégation est effectuée sur ce champ. Lorsqu’une agrégation de termes est effectuée, Elasticsearch doit pouvoir compter chaque terme unique. Par conséquent, ces termes uniques et leur décompte doivent être conservés en mémoire afin de générer ce type de résultats analytiques. De même, dans le cas d’une agrégation statistique, les données numériques d’un champ doivent être chargées afin de calculer les valeurs résultantes.

Ne pas craindre, cependant; comme je l’ai mentionné, bien que cela puisse sembler être une grande quantité de données à charger (et cela peut certainement l’être), Elasticsearch fait de son mieux pour charger les données de manière compressée. Cela dit, vous devez en être conscient. Discutons donc de la gestion des field data dans votre cluster.

6.9.3. Gestion des données des field data

Il existe plusieurs façons de gérer les field data dans un cluster Elasticsearch. Maintenant, que veut-on dire quand on dit «gérer»? Eh bien, gérer les field data signifie éviter les problèmes dans le cluster où le garbage collector de la JVM prend beaucoup de temps, ou alors le fait que trop de mémoire soit chargée, et provoque une erreur OutOfMemoryError; Il serait également utile d’éviter la perte de mémoire cache, afin que les données ne soient pas constamment chargées et déchargées de la mémoire.

Nous allons parler de trois manières différentes de gerer ce prévenir ce genre de problême:

  • Limiter la quantité de mémoire utilisée par les field data
  • Utilisation d’un circuit breaker pour les field data
  • Ignorer la mémoire, alléger la ram en utilisant le disque via le paramètre doc_value

Limiter la quantité de mémoire utilisée par les field data
Pour vous assurer que vos données ne prennent pas trop de place en mémoire, l’un des moyens les plus simples est de limiter le cache des field data à une certaine taille. Si vous ne le spécifiez pas, Elasticsearch ne limite pas le cache du tout et les données ne sont pas automatiquement expirées du cache après un laps de temps défini.

Il existe deux options différentes pour limiter le cache des field data: vous pouvez limiter la taille ou définir un délai d’expiration après lequel les données de champ du cache seront invalidées.

Pour définir ces options, spécifiez les éléments suivants dans votre fichier elasticsearch.yml. Ces paramètres ne peuvent pas être mis à jour via l’API des paramètres de mise à jour du cluster et nécessitent donc un redémarrage une fois modifiés:

Mais lorsque vous les définissez, il est plus judicieux de définir l’option indices.fielddata.cache.size à la place de l’option expire. Pourquoi? En effet, lorsque les données de champ sont chargées dans le cache, elles y resteront jusqu’à ce que la limite soit atteinte, puis elles seront expulsées de la manière LRU: last-recently-used. En définissant uniquement la limite de taille, vous supprimez également les données les plus anciennes du cache une fois la limite atteinte.

Lors de la définition de la taille, vous pouvez également utiliser une taille relative au lieu d’un absolu. Ainsi, au lieu des 400 Mo de notre exemple, vous pouvez spécifier 40% pour utiliser 40% de la taille de segment de mémoire de la jvm pour le cache des field data. Cela peut être utile si vous avez des machines avec différentes quantités de mémoire physique mais souhaitez unifier le fichier de configuration elasticsearch.yml entre elles sans spécifier de valeurs absolues.

Utilisation d’un circuit breaker pour les field data
Que se passe-t-il si vous ne définissez pas la taille du cache? Eh bien, afin de se protéger contre le chargement de trop de données en mémoire, Elasticsearch a le concept de circuit breaker, qui surveille la quantité de données en cours de chargement en mémoire et «déclenche» si une certaine limite est atteinte.

Dans le cas de field data, chaque circuit breaker évalue la quantité de mémoire requise pour les données et vérifie si leur chargement dépasse la taille maximale. Si c’est le cas, une exception est renvoyée et l’opération est empêchée.

Cela présente un certain nombre d’avantages: lorsqu’on applique une limite au cache de field data, la taille des field data ne peut être calculée qu’après le chargement des données en mémoire; il est donc possible de charger trop de données et de manquer de mémoire; En revanche, le circuit breaker estime la taille des données avant leur chargement afin d’éviter de les charger si le système manquerait de mémoire par la suite.

Un autre avantage de cette approche est que la limite du circuit breaker peut être ajustée dynamiquement pendant que le nœud est en cours d’exécution, tandis que la taille du cache doit être définie dans le fichier de configuration et qu’il est nécessaire de redémarrer le nœud pour la modifier. Le circuit breaker est configuré par défaut pour limiter la taille des données de champ à 60% de la taille du segment de mémoire de la machine virtuelle. Vous pouvez le configurer en envoyant une requête comme ceci:

Encore une fois, ce paramètre prend en charge une valeur absolue telle que 350 Mo ou un pourcentage tel que 45%. Une fois que vous avez défini cette option, vous pouvez voir la limite et la quantité de mémoire actuellement paramétrée au niveau du circuit breaker avec l’API Nodes Stats, dont nous parlerons au chapitre 11.



Depuis la version 1.4, il existe également un circuit breaker de requête, qui vous aide à vous assurer que les autres structures de données en mémoire générées par une requête ne provoquent pas une erreur OutOfMemoryError en les limitant à une valeur par défaut de 40%. Il existe également un circuit breaker parent, qui permet de s’assurer que les field data et les circuit breaker des query ne dépassent pas 70% du tas. Les deux limites peuvent être mises à jour via l’API Paramètres de mise à jour du cluster via indices.breaker.request.limit et indices.breaker.total.limit, respectivement.



Ignorer la mémoire et utiliser le disque avec des valeurs doc
Jusqu’ici, vous avez constaté que vous devriez utiliser des circuits breaker pour vous assurer que les requêtes en attente ne bloquent pas vos nœuds. Si vous manquez constamment d’espace de field data, vous devez augmenter la taille de votre segment de mémoire JVM pour utiliser davantage de RAM ou limiter la taille des field data et faire avec de mauvaises performances. Mais que se passe-t-il si vous manquez constamment d’espace de field data, et que vous n’avez pas assez de RAM pour augmenter la taille de la machine virtuelle et que vous ne pouvez pas vous contenter des mauvaises performances causées par des expulsions de field data (cache vidé)? C’est là qu’interviennent les doc_values.

Les doc_values prennent les données qui doivent être chargées en mémoire et les préparent plutôt lorsque le document est indexé, en les stockant sur disque à côté des données d’index standard. Cela signifie que lorsque les fields data sont normalement utilisées et lues en mémoire, elles peuvent être lues à partir du disque. Cela procure de nombreux avantages:

  • Les performances se dégradent moins rapidement– Contrairement aux field data par défaut, qui doivent vivre dans la JVM en même temps, les doc values sont lues à partir du disque, comme le reste de l’index. Si le système d’exploitation ne peut pas tout contenir dans le cache de la RAM, il faudra davantage de disques, mais cela ne demandera pas plus de ressources. Il n’y aura ni d’expulsions(cache vidé), ni risque d’erreurs OutOfMemory, ni d’exceptions venant du circuit breaker car il aura empêché les field data d’utiliser trop de cache mémoire.
  • Meilleure gestion de la mémoire – Lorsqu’elles sont utilisées, les doc_values sont mises en cache dans la mémoire par le noyau(kernel sur linux), ce qui évite le coût du garbage collector associé à l’utilisation du tas.
  • Chargement plus rapide— Avec les doc_values, la structure non inversée est calculée au moment de l’index. Ainsi, même lorsque vous exécutez la requête pour la première fois, Elasticsearch n’a pas à rétablir la structure non inversée de départ à la volée. Cela accélère les demandes initiales, car le processus a déjà été effectué au moment de l’indexation.

Comme pour tout dans ce chapitre, rien n’est gratuit. Les doc_value ont aussi des inconvénients:

  • Plus grande taille d’index – Le stockage de toutes les doc_values sur le disque gonfle la taille de l’index.
  • Indexation légèrement plus lente – la nécessité de calculer les doc_values au moment de l’index ralentit le processus d’indexation.
  • Ralentit légèrement les requêtes qui utilisent des field data – Le disque est également plus lent que la mémoire. Par conséquent, certaines requête utilisant normalement un cache field data déjà chargé en mémoire seront légèrement plus lentes lors de la lecture de doc_values à partir du disque. Cela inclut le tri, les facettes et les agrégations.
  • Ne fonctionne que sur les champs non analysés: à partir de la version 1.4, les docs values ne prennent pas en charge les champs analysés. Si vous souhaitez créer un nuage de mots dans les titres d’événements, par exemple, vous ne pouvez pas tirer parti des doc_values. Les doc_values peuvent être utilisées pour les champs numérique, date, booléen, binaire et géo-point, mais conviennent également aux grands ensembles de données contenant des données non analysées, telles que le champ d’horodatage des messages de logs indexés dans Elasticsearch.

La bonne nouvelle est que vous pouvez combiner et faire correspondre les champs qui utilisent des doc_values avec ceux qui utilisent le cache  mémoire sur les field data. Ainsi, même si vous souhaitez utiliser des doc_values pour le champ timestamps de vos événements, vous pouvez toujours conserver le titre de l’évènement en mémoire.

Comment sont utilisées les doc_values? Comme elles sont écrites au moment de l’indexation, la configuration des doc_values doit être effectuée dans le mapping d’un champ particulier. Si vous avez un champ de chaîne qui n’a pas été analysé et que vous souhaitez utiliser le paramètre doc_values dessus dessus, vous pouvez configurer le mapping lors de la création d’un index, comme indiqué dans la figure suivante.

Une fois le mapping configuré, l’indexation et la recherche fonctionneront normalement, sans modifications supplémentaires.

6.10. RÉSUMÉ

Vous avez maintenant une meilleure compréhension du fonctionnement du scoring dans Elasticsearch et de la manière dont les documents interagissent avec le cache field data. Voyons donc en quoi a consisté ce chapitre:

  • La fréquence d’un terme et le nombre de fois où il apparaît dans un document sont utilisés pour calculer le score d’un terme dans une requête.
  • Elasticsearch dispose de nombreux outils pour personnaliser et modifier le score.
  • L’impact du scoring peut être atténué en reévaluant (scoring de nouveau) un sous-ensemble de documents.
  • Utilisez l’API Explain pour comprendre comment un document a été évalué.
  • La requête function_score vous donne le contrôle ultime sur l’évaluation de vos documents.
  • La compréhension du cache field data peut vous aider à comprendre comment votre cluster Elasticsearch utilise la mémoire.
  • Des alternatives telles que doc_values ​​peuvent être utilisées si le cache de données de champ utilise trop de mémoire.

Au chapitre 7, nous verrons comment vous pouvez non seulement obtenir les résultats d’une requête, mais aussi explorer les données sous un angle différent en utilisant des agrégations.