web-dev-qa-db-fra.com

ElasticSearch: Impact de la définition d'un champ "non_analysé" comme "magasin": "oui"?

Supposons que j'ai un champ de chaîne spécifié comme not_analyzed dans le mappage. Si j'ajoute ensuite "store":"yes" au mappage, ElasticSearch dupliquera-t-il le stockage? Ma compréhension de not_analyzed champs signifie qu'ils ne sont pas exécutés via un analyseur, indexés tels quels, mais qu'un client est en mesure de les comparer. Donc, si un champ est à la fois not_analyzed et store:yes, cela pourrait amener ElasticSearch à conserver deux copies de la chaîne.

Ma question:

  • Si un champ de chaîne est stocké sous les deux not_analyzed et store:yes, y aura-t-il un stockage en double de la chaîne?

J'espère que c'est assez clair. Merci!

35
aaronlevin

Vous mélangez le concept de champ indexé et de champ stocké dans lucene, la bibliothèque sur laquelle elasticsearch est construite.

Un champ est indexé lorsqu'il entre dans l'index inversé, la structure de données que lucene utilise pour fournir ses capacités de recherche plein texte rapides et excellentes. Si vous souhaitez rechercher sur un champ, vous devez l'indexer. Lorsque vous indexez un champ, vous pouvez décider si vous souhaitez l'indexer tel quel ou l'analyser, ce qui signifie décider d'un tokenizer à lui appliquer, ce qui générera une liste de tokens (mots) et une liste de token des filtres qui peuvent modifier les jetons générés (même en ajouter ou en supprimer). La façon dont vous indexez un champ affecte la façon dont vous pouvez effectuer une recherche dessus. Si vous indexez un champ sans l'analyser et que son texte est composé de plusieurs mots, vous pourrez trouver ce document uniquement en recherchant ce texte spécifique exact, espaces compris.

Un champ est stocké lorsque vous souhaitez pouvoir le récupérer. Disons que Lucene fournit également une sorte de stockage, qui n'a rien à voir avec l'index inversé lui-même. Lorsque vous effectuez une recherche à l'aide de lucene, vous obtenez une liste des identifiants de document qui correspondent. Ensuite, vous pouvez récupérer du texte à partir de leurs champs stockés, ce que vous affichez littéralement comme résultats de recherche. Si vous ne stockez pas un champ, vous ne pourrez jamais le récupérer de lucene (ce n'est pas vrai pour elasticsearch cependant, comme je vais l'expliquer ci-dessous).

Vous pouvez avoir des champs sur lesquels vous souhaitez uniquement rechercher et ne jamais afficher: indexés et non stockés (par défaut dans lucene).
Vous pouvez avoir des champs que vous souhaitez rechercher et également récupérer: indexés et stockés.
Vous pouvez avoir des champs sur lesquels vous ne voulez pas rechercher, mais vous voulez les récupérer pour les afficher.

Par conséquent, les deux structures de données ne sont pas liées l'une à l'autre. Si vous indexez et stockez un champ dans lucene, son contenu ne sera pas présent deux fois sous la même forme. Les champs stockés sont stockés tels quels, lorsque vous les envoyez à lucene, tandis que les champs indexés peuvent être analysés et feront partie de l'index inversé, ce qui est autre chose. Les champs stockés sont faits pour être récupérés pour un document spécifique (par lucene document id), tandis que les champs indexés sont faits pour rechercher, dans une telle structure qui inverse littéralement le texte ayant comme résultat chaque terme comme clé, avec une liste de documents les identifiants qui le contiennent (la liste des publications).

En ce qui concerne la recherche sur les élastiques, les choses changent cependant un peu. Lorsque vous ne configurez pas un champ tel qu'il est stocké dans votre mappage (la valeur par défaut est store:no) vous pouvez quand même le récupérer par défaut. Cela se produit car elasticsearch stocke toujours dans lucene tout le document source que vous lui envoyez (sauf si vous désactivez cette fonction) dans un champ lucene spécial, appelé _ source .

Lorsque vous effectuez une recherche à l'aide d'elasticsearch, vous récupérez par défaut l'intégralité du champ source, mais vous pouvez également demander des champs spécifiques. Dans ce cas, elasticsearch vérifie si ces champs spécifiques sont stockés ou non dans lucene. S'ils le sont, le contenu sera récupéré depuis lucene, sinon le _source le champ stocké sera récupéré depuis lucene, analysé comme json (pull parsing) et ces champs spécifiques seront extraits. Dans le premier cas, cela pourrait être un peu plus rapide, mais pas nécessairement. Si votre source est vraiment volumineuse et que vous ne voulez charger que quelques champs, les configurer comme stockés dans lucene rendrait probablement le processus de chargement plus rapide; d'autre part, si votre _source n'est pas si grand et vous voulez charger plusieurs champs, alors il vaut probablement mieux ne charger qu'un seul champ stocké (le _source), ce qui entraînerait une recherche de disque unique, l'analyse, etc. Dans la plupart des cas, l'utilisation de _source field fonctionne très bien.

Pour répondre à votre question: index inversé et stockage lucene sont deux choses complètement différentes. Vous finissez par avoir deux copies des mêmes données dans lucene uniquement si vous décidez de stocker un champ (store:yes dans le mappage), car elasticsearch conserve le même contenu dans json _source, mais cela n'a rien à voir avec le fait que vous indexez ou analysez le champ.

91
javanna