Elasticsearch partie 2 : Les requêtes
Dans le premier article sur elasticsearch, nous avons fait une brève introduction sur le Devtools de Kibana. Dans cet article nous l’utiliserons pour effectuer des requêtes sur notre dataset. Si vous n’avez pas lu le premier article dans lequel j’ai effectué l’introduction générale sur elasticsearch, je vous le conseille.
Avant de commencer il faut savoir qu’elasticsearch ne s’utilise pas en tant que base de données primaire, il sert plutôt à indexer les données pour la recherche. La syntaxe des requêtes elasticsearch est simple, on en parlera pas dans cet article mais si vous voulez en savoir davantage leur documentation est bien détaillée. On distingue plusieurs types de requêtes parmi lesquelles (via la documentation d’elasticsearch) on a :
Dans cet article nous travaillerons plus avec les deux premiers types de requête.
Pour effectuer une recherche efficace sur notre index, il est important de connaitre sa structure et ce qu’il contient. Comme vu dans le premier article, notre index contient l’ensemble des articles publiés par Seth Godin sur son blog depuis janvier 2002 jusqu’en mai 2020. On va voir durant ces années quels sont les sujets sur lesquels il a beaucoup plus publié, les articles les plus aimés, l’année où il a le plus publié etc. Pour rappel chaque article est composé d’un titre, d’une date de publication, d’un contenu plain et HTML, du nombre de stars.
Match Query
La requête match permet de faire une correspondance entre les mots-clés à rechercher avec le contenu des documents. On peut spécifier les propriétés sur lesquels effectuer la recherche, l’opérateur entre les mots-clés OR ou AND, par défaut c’est OR. La requête suivante permet de rechercher tous les articles contenant « Amazon » dans leur titre.
GET sethgodin_blogs/_search
{
"query": {
"match":{
"title": "Amazon"
}
}
}
Résultat :
Le résultat de la recherche est constitué de plusieurs informations utiles. Comme le temps que la recherche a pris took, le nombre total des documents dans le résultat hits.total.value, les dix premiers documents du résultat hits.hits sur le nombre total avec chacun un _score attribué selon sa pertinence par rapport au mot-clé de la recherche etc.
Multi Match Query
Le multi_match permet d’effectuer la recherche sur plusieurs champs, par exemple ici nous recherchons tous les articles qui contiennent le mot-clé Apple à la fois dans le titre et dans le contenu de l’article.
GET sethgodin_blogs/_search
{
"query": {
"multi_match": {
"query": "Apple",
"fields": ["title","content_plain"]
}
}
}
Résultat :
Match Phrase Query
Si nous recherchons un titre d’un article contenant la phrase Mac fans are crowing about Apple’s en utilisant la requête match, nous aurons comme résultats tous les documents contenant soient Mac ou fans ou are ou crowing ou about ou Apple's. Si nous voulons avoir exactement les articles contenant "Mac fans are crowing about Apple’s" dans le même ordre des mots, il faut utiliser la requête match_phrase.
GET sethgodin_blogs/_search
{
"query": {
"match_phrase": {
"content_plain": "Mac fans are crowing about Apple’s"
}
}
}
Résultat :
On voit qu’on a exactement un seul document (total.value = 1) qui contient cette phrase.
NB: Il existe d’autres requêtes commençant par match, le principe reste le même. Pour en savoir davantage sur les autres matchs, je vous suggère la documentation d’elasticsearch.
Query string
La query_string permet de chercher les documents selon une chaîne de caractères fournie. La chaîne fournie inclut à la fois les mots-clés de la recherche et les opérateurs entre ces mots.
GET sethgodin_blogs/_search
{
"query": {
"query_string": {
"default_field": "content_plain",
"query": "Microsoft AND Google"
}
}
}
Résultat :
Il existe une requête similaire, simple_query_string qui ne prend pas l’option default_field, elle permet de rechercher ainsi dans tous les champs sans besoin de connaître la structure des documents.
Range Query
Cette requête retourne les documents respectant un intervalle fourni, par exemple nous voulons récupérer tous les articles ayant un nombre de stars compris entre 500 et 1000.
GET sethgodin_blogs/_search
{
"query": {
"range": {
"stars": {
"gte": 500,
"lte": 1000
}
}
}
}
Résultat :
Recommandé par LinkedIn
Fuzzy Query
Cette requête seule, ou combinée avec d’autres requêtes comme match, permet de retourner les résultats proches du mot clé de la recherche. Par exemple si on recherche un article qui parle de Facebook, mais on écrit Facebok comme mot-clé, on doit avoir le même résultat comme si on avait saisi Facebook.
GET sethgodin_blogs/_search
{
"query": {
"match": {
"title": {
"query": "Facebok",
"fuzziness": 1
}
}
}
}
Résultat :
Bool Query
Elle permet de mieux affiner une recherche en combinant plusieurs requêtes. Elle est constituée de 3 parties, must qui contient les requêtes obligatoires, should pour les requêtes qui ne sont pas obligatoires mais intéressantes, et filter pour filtrer le résultat de la recherche.
Dans notre exemple, nous souhaitons récupérer tous les articles dont le titre commence par What, les titres contenant what et marketing sont à prioriser et enfin tous les articles doivent avoir un nombre de stars supérieur à 2000. Traduisons maintenant notre exemple en requête Elasticsearch :
GET sethgodin_blogs/_search
{
"query": {
"bool": {
"must": [
{
"match_phrase_prefix": {
"title": "What"
}
}
],
"should": [
{
"match": {
"title": "Marketing"
}
}
],
"filter": [
{
"range": {
"stars": {
"gte": 2000
}
}
}
]
}
}
}
Résultat :
Booster une requête
Chaque document apparaissant dans un résultat de recherche dispose d’un score en fonction de sa pertinence par rapport aux termes de la recherche. Ce score par défaut est calculé par elasticsearch, mais il peut être modifié.
En effectuant une recherche sur les articles qui parlent de Microsoft, il est clair que les articles contenant le terme Microsoft dans leur titre sont plus pertinents. Pour cela nous allons booster tous les articles contenant Microsoft dans leur titre.
Avant le boost :
Après le boost :
GET sethgodin_blogs/_search
{
"query": {
"multi_match": {
"query": "Microsoft",
"fields": ["content_plain","title^3"]
}
}
}
Résultat :
Après avoir boosté la propriété title de 3 nous avons le résultat suivant.
Le highlight
Il permet de mettre en évidence le mot-clé de la recherche. Il prend plusieurs options, comme le tag personnalisé pour la mise en évidence etc. Par défaut le tag est la balise <em></em>.
Conclusion
Dans cet article nous avons exploré une partie des requêtes elasticsearch, il en existe une panoplie pour la recherche, l’agrégation ou la suggestion de recherche. C’est bien beau de connaitre toutes ces requêtes, l’idéal est de savoir comme on va les utiliser dans un vrai projet. Ça sera l’objectif du dernier article de notre série, une application de recherche en temps réel avec elasticsearch. Rejoignez-moi sur LinkedIn pour être notifié quand le prochain article sera publié.