Introduction à l’utilisation d’Elasticsearch

De Fabien Gaujous dans Technique

13 nov 2013

Si vous en avez assez des requêtes SQLs, des “like ‘%david%’” en guise de recherche textuelle et des jointures pour chaque donnée à rechercher,
c’est peut-être le bon moment de tester Elasticsearch même si le nombre de documents à indexer n’est pas de plusieurs millions, vous pourrez même gagner fortement en performance.
C’est sur cette base que nous avons installé notre premier serveur Elasticsearch après avoir entendu de très bon retours sur les réseaux et lors des conférences tels que DEVOXX.

Cet article décrit la mise en place et l’utilisation d’Elasticsearch sur un de nos projets (indexation,river..)
Attention, ce n’est pas une explication sur les bases de son installation et de son fonctionnement puisque de nombreux blogues existent déjà à ce sujet (Par exemple, cet article de Zenika sur les bases d’Elasticsearch)

Mise en place et utilisation d’Elasticsearch

Notre application, basée sur un modèle Entity-Attribute-value, créé il y a un certain nombre d’années ;-) , répond parfaitement aux besoins de CRUD et d’ajout dynamique de champs.
Cependant, la demande de recherche de plus en plus complexe et notamment textuelle nous a emmené à mettre en place un moteur de recherche adéquat.
Un export XML structuré (complet mais complexe) de chaque entité existait mais servait seulement à diffuser les informations à des systèmes tiers sans exploitation des données qu’elles possédaient. Pourtant les données dans ces fichiers étaient bien plus faciles à retrouver que via la base de données puisque celles-ci étaient dé-normalisées.
Voici les différentes étapes qui nous ont permis d’utiliser Elasticsearch comme moteur de recherche (prérequis : Elasticsearch est installé et fonctionne correctement)

  1. Elasticsearch acceptant des données sous format JSON, Une transformation XSLT via cette librairie s’opère à chaque création d’un fichier XML pour créer son “jumeau” au format JSON.
  2. Une des principales qualités à Elasticsearch, comparé par exemple à un serveur concurrent tel que Solr, est son mapping dynamique.
    Dans notre cas, au vu de la complexité du JSON, cela nous à apporté un réel gain de temps. Cependant, des modifications ont dû être apportées au mapping généré par Elasticsearch lors de l’insertion du premier JSON comme par exemple :
    • Le changement de type (double –> string)
    • La mise en place de champs de type multi_field
    • La mise à jour de l’analyzer

Pour commencer, créons l’index “index1″:

1
2
3
4
5
6
7
8
9
10
11
curl -XPUT http://localhost:9200/index1/ -d
'
{
"settings" : {
"index" : {
"number_of_shards" : 2,
"number_of_replicas" : 1
}
}
}
'

Une fois l’index créé, le type “type1″ est créé automatiquement ainsi que son mapping lors de l’insertion d’un fichier JSON (produit précédemment) via la commande :

1
curl -XPUT -d @45.json http://localhost:9200/index1/type1/45

45 correspondant à l’id de l’entité à insérer

La récupération du mapping nouvellement créé s’effectue rapidement :

1
curl http://localhost:9200/index1/type1/_mapping > mapping.json

Une fois le mapping modifié depuis le fichier mapping.json, il faut au préalable supprimer le type précédemment créé afin de recréer le mapping complet correct (En effet, nous ne pouvons pas mettre à jour le mapping à la volée sans réindexation).

1
2
curl -XDELETE -d @mapping.json http://localhost:9200/index1/type1/
curl -XPUT -d @mapping.json http://localhost:9200/index1/type1/_mapping

Voici un exemple de mapping simple pour le type “type1″ contenant seulement une propriété “name”

1
2
3
4
5
6
7
8
9
10
{
"type1": {
"properties": {
            "name" : {
            "type" : "string",
            "store" : true
           }
        }
    }
}

Une fois Elasticsearch configuré, nous avons décidé d’insérer les données via la “River” FS River puisque nous avions sur le système de fichiers tous les fichiers JSON à indexer.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
curl -XPUT http://localhost:9200/_river/baseproduit/_meta -d @produit_fs_river.json
'{
"type": "fs",
"fs": {
"url": "/json",
"update_rate": 10000,
"json_support": true,
"filename_as_id": true
},
"index": {
"index": "index1",
"type": "type1",
"bulk_size": 50
}
}'

Les fichiers JSON sont tous indexés dans Elastic Search au premier lancement, puis chaque entité individuellement,à chaque mise à jour du fichier JSON associé.

Attention, un problème existe avec l’attribut json_support : les fichiers, lorsqu’ils sont supprimés du dossier, ne sont pas supprimés de Elasticsearch (Voir le lien suivant : https://github.com/dadoonet/fsriver/issues/32)
Pour info, Les rivers vont être dépréciées au profit de l’utilisation de Logstash afin de recentrer la fonction principale d’Elasticsearch qui est l’indexation et la recherche (Voir cet interview de David Pilato qui explique l’évolution de Logstash pour gérer d’autres types de données que des logs).

Ces étapes nous ont servi à pouvoir rapidement mettre en place le serveur Elasticsearch et ainsi l’utiliser pour nos recherches sur n’importe quelle donnée sans écrire une seule requête SQL avec des temps de réponse nettement améliorés.
Des prochains articles arriveront très prochainement avec des astuces et des réponses aux questions à se poser pour une première mise en place d’Elasticsearch (Nombre de Shards/Nodes…).
Nous décrirons également la mise à disposition de cette recherche pour des applications tierces via des web services REST (JAVA).

1 Réponse pour Introduction à l’utilisation d’Elasticsearch

Avatar

David Pilato

novembre 13th, 2013 à 18 h 14 min

Cool! Merci :-)

Commentaire

+ sept = 16