Description :

Nous allons voir quelques bases sur Elasticsearch qui est un moteur de recherche puissant.
Ce moteur se base sur Lucene pour l'indexation et la recherche.

Terminologie :

  • index : collection de documents, est l'équivalent d'une base de données dans un SGBD.
  • document : donnée unitaire contenue dans un index, équivalent à une ligne dans un SGBD. Un document peut avoir plusieurs champs.
  • type : classe de document similaire, pourrait être l'équivalent de la table en SGBD. Il peut y eb avoir plusieurs par index.
  • mapping : définition explicite ou implicite des caractèristiques des champs à indexer, équivalent au schéma en SGBD.
  • node : instance (processus) Elasticsearch.
  • cluster : ensemble de node Elasticsearch sur lesquels sont répartis des index.
  • id : identifiant d'un document.
  • primary shard : chaque document est stocké dans un primary shard. Quand un document est indéxé, il est en premier dans le primary shard puis tous les replicas.
  • replica shard : chaque primary shard a 0 ou plusieurs replicas, un replica est une copie du primary shard
  • field : c'est une association de clé/valeur, un document contient une liste de fields.

shards

Note :
Les documents sont stockés au format JSON et ont un index, un type et un id en plus des données.
Plusieurs nodes peuvent être lancés sur un même serveu, mais il est conseillé d'en avoir qu'un par serveur.
Les replicas shard ont 2 fonctionnalités :

  • augmenter le failover : un replica shard peut être promu primary shard en cas d'incident.
  • augmenter les performances : les requêtes get et search peuvent être traitées sur les primary et replicas shard.

Indexation :

Character Filters
Traitement des chaînes de caractères avant de les passer au tokenizer.
Par exemple supprimer les tags HTML.

Tokenizer
Segmenter la chaîne de caractères en termes.

Token Filters
Application de filtres sur les termes comme par exemple, passer les termes en lowercase, supprimer les stopwords, ....

insertion donnees

Exemple avec le character filter html_strip et tokenizer standard

 1 curl -XGET 'http://localhost:9200/_analyze?tokenizer=standard&char_filters=html_strip&pretty=true' -d 'Elasticsearch est <strong>Génial</strong>'
 2 {
 3   "tokens" : [ {
 4     "token" : "Elasticsearch",
 5     "start_offset" : 0,
 6     "end_offset" : 13,
 7     "type" : "<ALPHANUM>",
 8     "position" : 1
 9   }, {
10     "token" : "est",
11     "start_offset" : 14,
12     "end_offset" : 17,
13     "type" : "<ALPHANUM>",
14     "position" : 2
15   }, {
16     "token" : "Génial",
17     "start_offset" : 26,
18     "end_offset" : 41,
19     "type" : "<ALPHANUM>",
20     "position" : 3
21   } ]
22 }

Ajoutons un token filter lowercase

 1 curl -XGET 'http://localhost:9200/_analyze?tokenizer=standard&char_filters=html_strip&filters=lowercase&pretty=true' -d 'Elasticsearch est <strong>Génial</strong>'
 2 {
 3   "tokens" : [ {
 4     "token" : "elasticsearch",
 5     "start_offset" : 0,
 6     "end_offset" : 13,
 7     "type" : "<ALPHANUM>",
 8     "position" : 1
 9   }, {
10     "token" : "est",
11     "start_offset" : 14,
12     "end_offset" : 17,
13     "type" : "<ALPHANUM>",
14     "position" : 2
15   }, {
16     "token" : "génial",
17     "start_offset" : 26,
18     "end_offset" : 41,
19     "type" : "<ALPHANUM>",
20     "position" : 3
21   } ]
22 }

D'autres filtres existent comme

  • asciifolding : transforme les caractères Basic Latin Unicode Block (é, à, ç, ð, æ, ...) en caractère ascii.
  • worddelimiter : permet de séparer un terme en plusieurs.
  • stopword : permet de supprimer des mots peu important (de, à, qui, que, ...) via une liste.
  • snowball : permet de tronquer des termes selon un stemmer (racine), exemple il va garder "developpe" pour "développer", "développement", "développeur" ...
  • elision : supprime les termes peu important comme le "j" du "j'".
  • ...

Il est possible de définir ses propres filtres.

Recherche :

C'est un moteur de recherches full text.
Nous allons voir la recherche via des exemples, mais sans token filter ou autre.

Création d'un index poc-es

1 curl -XPUT 'http://127.0.0.1:9200/poc-es/'
2 {"acknowledged":true}

Création de documents

 1 curl -XPUT 'http://localhost:9200/poc-es/docPOC/1' -d '{
 2 >     "mot" : "chartePRA",
 3 >     "post_date" : "2016-04-29T14:12:12",
 4 >     "message" : "trying out Elasticsearch"
 5 > }'
 6 {"index":"poc-es","type":"docPOC","id":"1","version":1,"created":true}
 7 
 8 curl -XPUT 'http://localhost:9200/poc-es/docPOC/2' -d '{
 9 >     "mot" : "chartepRa",
10 >     "post_date" : "2015-04-29T14:12:12",
11 >     "message" : "trying out Elasticsearch"
12 > }'
13 {"index":"poc-es","type":"docPOC","id":"2","version":1,"created":true}

Requête sur le terme chartePRA du field mot

 1 curl 'http://127.0.0.1:9200/poc-es/search?q=mot:chartePRA&size=5&pretty=true'
 2 {
 3   "took" : 3,
 4   "timed_out" : false,
 5   "shards" : {
 6     "total" : 5,
 7     "successful" : 5,
 8     "failed" : 0
 9   },
10   "hits" : {
11     "total" : 2,
12     "max_score" : 0.30685282,
13     "hits" : [ {
14       "index" : "poc-es",
15       "type" : "docPOC",
16       "id" : "1",
17       "score" : 0.30685282,
18       "source":{
19     "mot" : "chartePRA",
20     "post_date" : "2016-04-29T14:12:12",
21     "message" : "trying out Elasticsearch"
22 }
23     }, {
24       "index" : "poc-es",
25       "type" : "docPOC",
26       "id" : "2",
27       "score" : 0.30685282,
28       "source":{
29     "mot" : "chartepRa",
30     "post_date" : "2015-04-29T14:12:12",
31     "message" : "trying out Elasticsearch"
32 }
33     } ]
34   }
35 }

la requête peut aussi s'écrire :

1 curl -XPOST 'localhost:9200/poc-es/_search?pretty' -d '
2 {
3   "query": { "match": { "mot": "chartePRA" } }
4 }'

On s'aperçoit que la recherche ne tient pas compte de la casse.
Attention le matching est fait sur le mot complet, pour du contains il faut utiliser les wildcard * et ?.
Les caractères spéciaux sont assimilés à des espaces.