Comprendre le DSL de requête d’Elasticsearch

Pas seulement copier-coller de Stack Overflow mais comprendre ce que vous copiez-coller.

Elasticsearch est le moteur de recherche de référence ces jours-ci, mais son DSL de requête a une courbe d’apprentissage raide. Lorsque j’ai commencé à écrire des requêtes Elasticsearch, je pouvais enchaîner quelque chose qui fonctionnait grâce à une combinaison des docs d’Elastic.co et de Stack Overflow, mais je ne comprenais pas complètement les concepts sous-jacents derrière la syntaxe.

Ce tutoriel vise à être ce que j’aurais aimé avoir lu en premier. Il suppose que le lecteur est familier avec les concepts de base d’Elasticsearch, peut écrire des requêtes simples et comprend la logique booléenne. Il vise à fournir au lecteur une base conceptuelle solide d’Elasticsearch avant d’essayer de comprendre la syntaxe.

Filtrage par valeurs exactes vs Recherche analysée en texte intégral

Un thème primordial dans Elasticsearch est que toutes les requêtes peuvent être classées en trois types :

1. Filtrage par valeurs exactes
2. Recherche sur le texte analysé
3. Une combinaison des deux

Chaque champ de document peut être classé soit comme valeurs exactes, soit comme texte analysé (également appelé texte complet). Les valeurs exactes sont des champs comme user_iddateemail_addresses, etc. Le texte analysé est une donnée textuelle comme product_description ou email_body. Comme son nom l’indique, ces données textuelles ont été analysées (nous y reviendrons plus tard). Il est souvent dans un langage naturel humain mais pas nécessairement.

L’interrogation des documents peut se faire en spécifiant des filtres sur des valeurs exactes. Dans ces cas, la question de savoir si le document est retourné est un oui ou un non binaire. Par exemple, la user_id du document est-elle égale à 174517 ? La date created_at du document est-elle comprise dans la plage du mois dernier ?

En revanche, l’interrogation de documents par recherche de texte analysé renvoie des résultats basés sur la pertinence. Un document est renvoyé non pas en fonction d’un critère oui/non, mais en fonction de sa pertinence. Par exemple, si le texte analysé d’un document comprend Johnny Depp, il devrait également être retourné dans les recherches de John Depp ou Johnnie Depp. Une recherche pour cook devrait également retourner des résultats pour cooking et cooked.

De ce comportement, nous pouvons déduire que la recherche par texte analysé est une opération très complexe et implique différents paquets d’analyseurs selon le type de données textuelles. Par exemple, certains paquets d’analyseurs sont spécifiques à la langue qui sont utilisés sur le texte dans une certaine langue. Le paquet d’analyseurs par défaut est l’analyseur standard qui divise le texte en fonction des limites des mots, des minuscules et de la ponctuation. Comme la recherche par texte analysé est beaucoup plus compliquée que le filtrage par valeurs exactes, elle est beaucoup moins performante que le simple filtrage par valeurs exactes. Remarque, nous appellerons la recherche par texte analysé comme recherche analysée pour faire court.

Le DSL de requête

Les requêtes d’Elasticsearch sont composées d’une ou plusieurs clauses de requête. Les clauses de requête peuvent être combinées pour créer d’autres clauses de requête, appelées clauses de requête composées. Toutes les clauses de requête ont l’un ou l’autre de ces deux formats :

{
QUERY_CLAUSE: {
ARGUMENT: VALUE,
ARGUMENT: VALUE,...
}
}{
QUERY_CLAUSE: {
FIELD_NAME: {
ARGUMENT: VALUE,
ARGUMENT: VALUE,...
}
}
}

La règle syntaxique est que les clauses de requête peuvent être imbriquées de manière répétée à l’intérieur d’autres clauses de requête

{
QUERY_CLAUSE {
QUERY_CLAUSE: {
QUERY_CLAUSE: {
QUERY_CLAUSE: {
ARGUMENT: VALUE,
ARGUMENT: VALUE,...
}
}
}
}
}

Voici quelques clauses de requête courantes.

Clause de requête match

La clause de requête match est la clause de requête la plus générique et la plus utilisée. Elle est assez intelligente dans la mesure où, lorsqu’elle est exécutée sur un champ de texte analysé, elle effectue une recherche analysée sur le texte. Lorsqu’elle est exécutée sur un champ à valeur exacte, elle effectue un filtre.

Dans l’exemple ci-dessous, la première clause de requête effectuera une recherche analysée puisque description est un champ de texte analysé. Alors que les 2 autres requêtes sont des filtres sur des champs à valeur exacte.

{ "match": { "description": "Fourier analysis signals processing" }}
{ "match": { "date": "2014-09-01" }}
{ "match": { "visible": true }}

La clause de requête match all

La clause de requête match all renvoie tous les documents. Elle est analogue à SELECT * FROM table en SQL.

{ "match_all": {} }

La clause de requête term/terms

Les clauses de requête term et terms sont utilisées pour filtrer un champ à valeur exacte par des valeurs uniques ou multiples, respectivement. Dans le cas de valeurs multiples, le lien logique est OR .

Par exemple, la première requête trouve tous les documents avec la balise « math ». La deuxième requête trouve tous les documents avec les balises « maths » ou « statistiques ».

{ "term": { "tag": "math" }}
{ "terms": { "tag": }}

Clause de requête à correspondances multiples

La clause de requête à correspondances multiples est une requête de correspondance qui est exécutée sur plusieurs champs au lieu d’un seul.

{
"multi_match": {
"query": "probability theory",
"fields":
}
}

Clause de requête des filtres existants et manquants

Le filtre existant vérifie que les documents ont une valeur à un champ spécifié. Le filtre missing vérifie que les documents n’ont pas de valeur à un champ spécifié. Ils sont analogues aux clauses IS NULL et IS NOT NULL de SQL.

{
"exists" : {
"field" : "title"
}
}

et

{
"missing" : {
"field" : "title"
}
}

Clause de requête de filtre de plage

La clause de requête de filtre de plage est utilisée pour filtrer les champs de nombres et de dates dans des plages, en utilisant les opérateurs gtgteltlte abréviation de greater_thangreater_than_or_equalless_than et less_than_or_equal , respectivement.

{ "range" : { "age" : { "gt" : 30 } } }{ 
"range": {
"born" : {
"gte": "01/01/2012",
"lte": "2013",
"format": "dd/MM/yyyy||yyyy"
}
}
}

Clauses de requête composées

Les clauses de requête qui sont construites à partir d’autres clauses de requête sont appelées clauses de requête composées. Notez que les clauses de requête composées peuvent également être composées d’autres clauses de requête composées, ce qui permet une imbrication multicouche.

La clause de requête bool est un exemple de clause de requête composée, car elle est utilisée pour combiner plusieurs clauses de requête à l’aide d’opérateurs booléens. Les trois opérateurs booléens pris en charge sont mustmust_not et should , qui correspondent respectivement à ANDNOT , et OR .

Par exemple, supposons que nous ayons un index sur le posts d’un site de médias sociaux populaire. Voici une requête pour trouver toutes les posts sur les mathématiques qui ne sont pas des probabilités, où elles sont soit non lues, soit ont été favorisées.

{
"bool": {
"must": { "term": { "tag": "math" }},
"must_not": { "term": { "tag": "probability" }},
"should":
}
}

Combinaison de la recherche analysée avec des filtres

Nous avons parlé des filtres de champ exact et de la recherche analysée dans des contextes séparés, mais dans les applications du monde réel, nous voulons souvent combiner les deux. Nous combinons la recherche analysée et les filtres de champs exacts à l’aide de la clause filtered.

Par exemple, supposons que nous avons un index sur le posts d’un forum web populaire sur les mathématiques. Voici une requête pour trouver tous les messages en effectuant une recherche analysée pour « Probability Theory », mais nous ne voulons que les posts avec 20 upvotes ou plus et pas ceux avec ce tag « frequentist ».

{
"filtered": {
"query": { "match": { "body": "Probability Theory" }},
"filter": {
"bool": {
"must": {
"range": { "upvotes" : { "gt" : 20 } }
},
"must_not": { "term": { "tag": "frequentist" } }
}
}
}
}

Summary

La toile de fond conceptuelle du DSL de requête Elasticsearch est cette dichotomie entre le filtrage de documents et la recherche dans le texte analysé. J’espère que vous avez trouvé cela utile.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *