ElasticaSearch

Recherche géolocalisée avec Elasticsearch et Symfony 2

Je vous propose dans cet article de mettre en place un moteur de recherche géolocalisé dans votre projet Symfony 2.

Il existe à ce jour de nombreux moyens de faire des recherches sur un site web : Google Search, recherche full text MySql, Lucene / Solr, Zend Lucene…
Aujourd’hui j’ai décidé d’utiliser ElasticSearch (http://www.elasticsearch.org) qui est un moteur de recherche sous Java équivalent à Solr (Solr et Elasticsearch étant tout deux des surcouches de Apache Lucene). Le but de cet article n’étant pas de vous démontrer que untel est meilleur que l’autre… mais plutôt d’attirer votre attention sur une fonctionnalité spécifique à ElasticSearch : la recherche géolocalisée.

Sommaire :

 

1 – Rappel théorique

Avant de rentrer dans le vif du sujet, voici une formule de calcul de distance entre 2 points géolocalisés (appelée “distance orthodromique”) :

R x acos[cos(LatA) x cos(LatB) x cos(LongB-LongA)+sin(LatA) x sin(LatB)] = Distance en Km
avec R étant le rayon de la terre (environ 6 378 Km)

 

2 – Installation

2.1 – Installation de ElasticSearch

Tout d’abord, nous allons télécharger la dernière version stable de ElasticSearch sur :
http://www.elasticsearch.org/download/

Concernant l’installation d’ElasticSearch, il vous suffit d’extraire les sources téléchargées dans le dossier bin/ de votre projet Symfony 2 par exemple. Vous pouvez aussi l’installer ailleurs si vous souhaitez partager l’instance de votre moteur de recherche entre plusieurs projets.

Ensuite, lancer en ligne de commande votre moteur de recherche  :

Pour plus d’informations sur l’installation : http://www.elasticsearch.org/guide/reference/setup/installation.html

2.2 – Installation de FOQElasticaBundle

Nous allons ensuite installer le bundle FOQElasticaBundle de Exercise. Ajoutez dans votre composer.json :

Lancez ensuite l’installation de ce package et de ses dépendances (ruflin/elastica)

Pour plus d’information sur l’installation : https://github.com/Exercise/FOQElasticaBundle

2.3 – Déclaration du bundle

 

2.4 – Test du fonctionnement du bundle

En faisant un “app/console list foq” dans votre terminal, vous verrez que le bundle FOQElasticaBundle propose 2 commandes :

  • foq:elastica:populate va vous permettre de lancer l’indexation
  • foq:elastica:search va vous permettre de faire des recherche dans vos indexes

 

3 – Configuration

3.1 – Déclaration du client et du mapping

Concernant le mapping, lors de l’indexation, le système va faire appel aux getters correspondants sur l’entité indexée. Concrètement dans notre exemple, le système fera appel aux méthodes getUsername(), getPresentation() et getLocation() de l’entité ElaoUserBundleEntityUser

3.2 – Configuration de l’entité à indexer

Dans l’exemple ci-dessus, nous pouvons voir que nous renvoyons les propriétés $locationLat et $locationLng sous forme de tableau par l’intermédiaire de la méthode getLocation().

4 – Indexation

Maintenant que tout est installé et bien configuré, nous allons pouvoir lancer l’indexation.

Pour cela, rien de plus simple, il vous suffit de lancer la commande d’indexation (dont nous avons parlé quelques lignes plus haut) :

 

5 – Recherche

5.1 – Test de la recherche en ligne de commande

On va commencer par faire un test tout bête en ligne de commande de notre moteur de recherche :

Cette commande propose pas mal d’options qui vous aideront à débugger vos requêtes vers le moteur de recherche ou vous permettront aussi de mieux comprendre la syntaxe des requêtes JSON vers ElasticSearch.

5.2 – Contrôleur / Manager

En amont, nous avons un formulaire de recherche composé de 2 champs : “What”, “Where” (un peu à la façon du site des pages jaunes par exemple). Les valeurs de ces champs vont être envoyées à un contrôleur qui va les traiter et les envoyer à son tour à un manager.

On va tout d’abord créer ce Manager qui contiendra toute notre logique métier pour rechercher dans l’index du moteur de recherche :

Ce manager va construire une requête en fonction des paramètres passés à la fonction search(). Pour la recherche, nous avons besoin de passer au moteur de recherche une latitude et une longitude du point autour duquel nous souhaitons rechercher. Il vous est aussi possible de définir le périmètre dans lequel vous souhaitez rechercher.

Cette fonction renverra une Collection d’objets Doctrine. A vous ensuite de faire le nécessaire dans votre contrôleur/vue pour les afficher.

 

6 – Conclusion

On a pu voir à travers cet article qu’il était possible de mettre en place un moteur de recherche géolocalisée rapidement et facilement sur un projet Symfony 2. Concernant les performances, je n’ai pas fait de mesures mais elles semblent globalement satisfaisantes.

Vos commentaires ou vos questions sont les bienvenus et me permettront de compléter cet article si besoin.

Related posts:

2 thoughts on “Recherche géolocalisée avec Elasticsearch et Symfony 2

  1. Il ne faut pas mettre “sensor=true” dans l’appel a google maps.
    cette valeur sert pour essayer de geolocaliser l’utilisateur qui fait la requete.

    Ici, cela ne sert a rien ;)

  2. Bonjour,

    Merci pour ce Tuto! Par contre je débute en Symfony, et je n’arrive pas a appeler le Manager depuis mon controller… si jamais tu avais un indice pour me mettre sur la bonne voie je suis preneur!

    Merci

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>