ElasticSearch : Explication, Introduction et mise en pratique via FOSElastica Bundle

Cette article est très vieux et ne devrait pas être utilisé comme support pour votre travail.



Le client veut une recherche de dingue !

Et oui y’en a marre de la recherche toute pourrie à base de like en sql ! Non, on veut du gros, du gras, de la recherche phonétique  sur laquelle on met du filtre et le tout (presque)instantanément. Oui on veut de l’elasticsearch !

Mais elasticsearch c’est quoi ? Et bien c’est un moteur de recherche open source écrit en java basé sur Lucene. Il utilise une base de données NoSQL, codée au format JSON, qu’il indexe et interroge via une API rest.
Autrement dit via une requête HTTP PUT il va remplir et/ou mettre à jour ces fichiers JSON (la base de données) et via une autre requête HTTP GET il va accéder à ces données, et nous renvoyer ce qu’on recherche dans notre cher projet.

Il y en d’autres hein, comme dans tout rest le POST et le DELETE sont de la partie aussi.



We need to go deeper

OK mais comment ça marche la bête ? Pour comprendre il faut connaitre les termes utilisés dans le monde elastic.

Cluster : Le cluster est formé d’un ou plusieurs nodes. Le cluster va accueillir tous nos nodes et donc toutes nos données. Un cluster est formellement identifié par un nom. Par défaut ce nom est ‘elasticsearch’ mais on peut le modifier comme on le souhaite. Vous y viendrez si vous voulez plusieurs clusters.

Node : C’est une instance d’elasticsearch. Il fait partie de votre cluster comme dit plus haut. Il stocke vos données, participe à l’indexation mais aussi à la recherche. Comme le cluster, le node est identifié par un nom. Par défaut il lui est attribué un nom de héros Marvel (!!). Je vous conseille Iron Man, car Iron Man il est cool. Un node peut être configuré pour joindre un cluster spécifique par le nom de ce dernier, par défaut il cherchera à aller dans le cluster ‘elasticsearch’. Donc si vous ne touchez à rien et que vous lancer plusieurs nodes sur votre serveur, vous aurez alors plusieurs héros Marvel qui vont tous se joindre au cluster ‘elasticsearch’ ensemble. Tout  ça sachant que vous pouvez avoir autant de nodes que vous voulez dans un cluster.

Index : Un index est une collection de documents qui ont tous un point commun. Un index peut regrouper tous vos utilisateurs, un autre tous vos articles. En faite vous pouvez mettre n’importe quoi à partir du moment où ces données ont un point commun et qu’il est logique de les classer dans le même index pour une recherche.

Type : Il s’agit du typage  des index. Par exemple dans votre index article vous pouvez les typer par article sur Symfony2, Doctrine, MySQL etc etc..

Document :  C’est dans le document qu’est représentée la donnée. Elle est organisée avec des champs. De la même façon qu’une table avec des champs en MySQL. Cependant ici il s’agit d’une représentation NoSQL en JSON.



Installation

Je vais ici montrer la manière d’installer elasticsearch en services sur Linux Debian/Ubuntu.

Si vous n’êtes pas sur Linux ou si vous ne souhaitez pas l’installer en service allez voir de ce côté-là

On doit d’abord installer JAVA indispensable au bon fonctionnement d’elastic :

echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu precise main" | tee /etc/apt/sources.list.d/webupd8team-java.list
echo "deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu precise main" | tee -a /etc/apt/sources.list.d/webupd8team-java.list
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys EEA14886
apt-get update
apt-get install oracle-java8-installer

On va chercher le package via wget

wget "https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.7.1.deb"

On installe ensuite notre paquet

dpkg -i elasticsearch-1.7.1.deb

Par défaut elasticsearch n’est pas configuré pour redémarrer à chaque reboot serveur. On trouve cependant dans la documentation officielle une commande pour ça:

sudo update-rc.d elasticsearch defaults 95 10

Si vous souhaitez changer de nom de cluster et/ou de node ça se passe dans un fichier de config YAML à cet emplacement : /etc/elasticsearch/elasticsearch.yml

Quand tout est prêt lancer votre service comme n’importe quel autre service :

sudo /etc/init.d/elasticsearch start

Pour savoir si votre elasticsearch marche bien rendez-vous à cette adresse : http://localhost:9200



Les API REST c’est le bien



Et oui, c’est le bien, et elastissearch l’utilise et en abuse !
Ce format bien précis est utilisé pour y accéder :

http://localhost:9200/[index]/[type]/[_action|id]

Pour qu’elastic puisse trouver vos données il va falloir les indexer, cet à dire stocker tout ce que vous voulez dans sa base de données à lui.

Commençons par le commencement pour comprendre on va utiliser notre bon vieux terminal et on va indexer des données via CURL :

curl -XPUT 'http://localhost:9200/article/elasticsearch/1' -d '{
    "titre" : "ElasticSearch est le meilleur moteur de recherche",
    "contenu" : "Oui en effet",
    "date" : "2012-12-21T00:00:00",
    "url": "http://www.jesuisundev.fr/introduction-explication-elasticsearch/"
}'

Alors qu’avons-nous fait ici ?

On a simplement indexé notre article, via un PUT, dans l’index ‘article’ et le type ‘elasticsearch’, que nous avons créé au passage, on y a mit quatre champs avec des données qui sont désormais accessibles à une recherche !

Un joli message de type “{“_index”:”article”,”_type”:”elasticsearch”,”_id”:”1″,”_version”:1,”created”:true}” a dû apparaître nous indiquant que tout c’est bien passé, on peut maintenant faire une recherche !

curl -XGET 'http://localhost:9200/article/elasticsearch/_search?q=oui'

OUI ! Nous avons fait une recherche sure oui et Elastic malin comme il est, il a trouvé quelque chose :

{“took”:2,”timed_out”:false,”_shards”:{“total”:5,”successful”:5,”failed”:0},”hits”:{“total”:1,”max_score”:0.067124054,”hits”:[{“_index”:”article”,”_type”:”elasticsearch”,”_id”:”1″,”_score”:0.067124054,”_source”:{
“titre” : “ElasticSearch est le meilleur moteur de recherche”,
“contenu” : “Oui en effet”,
“date” : “2012-12-21T00:00:00”,
“url”: “http://www.jesuisundev.fr/introduction-explication-elasticsearch/”
}}]}}

C’est bien nos données et il est a trouvées car le mot ‘oui’ y apparaît !

De base il y a des trucs bien sympas genre :

curl -XGET 'http://localhost:9200/article/elasticsearch/_search?q=oi~'

Le mot oui est mal orthographié et pourtant notre article est trouvé  grâce au caractère : ‘~’ .

Il s’agit ici d’un seul épisode de ce que propose l’API d’elastic. La série entière est ici.



OK c’est cool mais on va pas tout se taper à la main

Bien sûr que non et c’est la qu’intervient nos amis de chez FOS et leur bundle !

Alors, je sous-entends que vous bosser sur Symfony2. Bien sûr, vous bosser sur Symfony2 hein ? Non?! Bon sinon il y a l’api PHP officiel  par la.

Concernant l’installation, je ne reviens pas dessus c’est clair, simple et limpide sur le Github.

Par contre au niveau de la  config on va regarder un petit peu :



fos_elastica:
    clients:
        default: { host: localhost, port: 9200 }
    indexes:
        jesuisundev:
            finder: ~
            types:
                article:
                    mappings:
                        title: ~
                        content: ~
                    persistence:
                        driver: orm
                        model: Acme\AcmeBundle\Entity\Article
                        provider: ~
                        listener:
                            immediate: ~
                        finder: ~
                user:
                    mappings:
                        username: ~
                        email: ~
                    persistence:
                        driver: orm
                        model: Acme\AcmeBundle\Entity\User
                        provider: ~
                        listener:
                            immediate: ~
                        finder: ~


Ici nous avons indiqué que notre host est la maison (localhost) et qu’il faut taper sur le port 9200.

Ensuite nous avons indiqué que l’index ou stocker nos données est ‘jesuisundev’. Nous avons demandé l’indexation de deux types dans cet index : ‘article’ et ‘user’.

Nous avons choisi qu’elle champs de notre entité sont indexés,  mais surtout demandé au bundle d’utiliser nos entités via doctrine ORM.
Le listener est là pour savoir quand et comment indexer vos nouvelles données.

Le tout étant évidemment configurable, vous trouverez plus d’info par ici.

php app/console fos:elastica:populate

Cette commande dans votre terminal et la magie opère ! Tout ce qui trouve dans votre entité sera indexé de façon automatique et disponible à la recherche ! Un petit coup d’utilisation de service et il n’y a plus qu’à afficher !



Épilogue

On pourrait écrire un livre sur Elasticsearch. En fait on pourrait faire plusieurs tomes.

Ici nous avons juste fait une introduction basique sur une première utilisation.

Mais cet outil est fait pour aller beaucoup plus loin, des recherches phonétiques, de la pluralisation, de l’adaptation à chaque langue, l’utilisation de facettes, des filtres à gogo et bien d’autres vous attendent avec ce fabuleux outil qui s’appelle google.

Ou alors, vous attendez mon second article là-dessus 😉

Qui me parle ?

jesuisundev
Je suis un dev. En ce moment je suis Backend Développeur / DevOps à Ubisoft. Je suis passionné du dev et j'écris comme je parle. Je continue à te parler quotidiennement sur mon Twitter. Tu peux m'insulter à cette e-mail ou le faire directement dans les commentaires juste en dessous.

Commentaire(s)

  1. bonjour,

    merci beaucoup. A quand le deuxième article ?

    Un petit article sur l’intertionalisation est il prévu ? par exemple faire un select qui change la locale.

    1. Bonjour !

      Merci pour votre intérêt !
      Le second article sur Elastic est effectivement en écriture et il sera sujet de recherche très avancées.
      Et l’internationalisation est une bonne idée, j’y penserais.

  2. Merci pour l’article.
    Du coup j’ai essayer de l’implémenter.
    Un petit exemple de route + controleur + form twig dans un prochain article ?

T'en penses quoi ?

Your email address will not be published. Required fields are marked *