Qu'est-ce qu'Elasticsearch ?

Elasticsearch est un moteur de recherche et d'analyse distribuée, open-source, basé sur Apache Lucene. Il permet de stocker, rechercher et analyser de gros volumes de données en temps quasi-réel.

? En bref : Un outil puissant pour effectuer des recherches ultra-rapides dans des millions de documents. Que vous ayez besoin de chercher dans des logs, des produits d'e-commerce, ou des articles de blog, Elasticsearch est conçu pour le faire avec une performance exceptionnelle.



4 Points Clés de Elasticsearch

? Moteur de recherche puissant

Recherche full-text avec scoring de pertinence, recherche floue, autocomplétion et support multilingue pour des résultats précis.

? Architecture distribuée

Scalabilité horizontale, haute disponibilité avec réplication et sharding automatique pour gérer des données massives.

? RESTful API

Toutes les opérations via HTTP/JSON. Facile à intégrer dans n'importe quelle stack technologique.

? Schema-less (flexible)

Indexation dynamique des documents JSON. Pas besoin de définir la structure à l'avance.

Ces quatre piliers font d'Elasticsearch une solution robuste et flexible pour tous vos besoins de recherche, qu'ils soient simples ou complexes.



Installation de Elasticsearch

Installation avec Docker

La façon la plus simple et recommandée d'installer Elasticsearch est d'utiliser Docker. Voici une configuration Docker Compose complète :

elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.17.4
    container_name: elasticsearch
    ulimits:
        memlock:
            soft: -1
            hard: -1
    environment:
        - discovery.type=single-node
        - transport.host=127.0.0.1
        - xpack.security.enabled=false
        - xpack.security.enrollment.enabled=false
    cap_add:
        - IPC_LOCK
    ports:
        - "9200:9200"
    volumes:
        - elastica:/usr/share/elasticsearch


Installation du Bundle Symfony

Si vous utilisez Symfony, installez le FOSElasticaBundle qui facilite l'intégration :

composer require friendsofsymfony/elastica-bundle



Configuration d'Elasticsearch

Configuration des clients

Dans votre fichier fos_elastica.yaml, commencez par configurer la connexion :

fos_elastica:
     clients:
         default:
             hosts: [ '%env(resolve:ELASTICSEARCH_URL)%' ]


Configuration de l'index

Ensuite, définissez vos index, leurs shards et replicas, ainsi que les analyzers :

    indexes:
         user:
             index_name: studea_%kernel.environment%_user_PLATFORM
             settings:
                 number_of_shards: 1
                 number_of_replicas: '%env(int:ELASTICSEARCH_REPLICAS)%'
             index:
                 analysis:
                     analyzer:
                         custom_french_analyzer:
                             tokenizer: standard
                             filter: [ "asciifolding", "lowercase" ]


Configuration des properties

Définissez le mapping des champs que vous indexez :

           properties:
                 firstname:
                     type: text
                     copy_to: fullName
                 lastname:
                     type: text
                     copy_to: fullName
                 fullName:
                     type: text

? Astuce : Utilisez copy_to pour combiner plusieurs champs dans un seul champ virtuel. C'est très utile pour la recherche full-text.



Créer et peupler un index

Une fois votre configuration en place, vous devez créer l'index et le remplir avec vos données :

Créer la structure de l'index

php bin/console fos:elastica:create

Cette commande crée la structure de l'index dans Elasticsearch selon vos paramètres de configuration.


Indexer les données existantes

php bin/console fos:elastica:populate

Cette commande crée la structure de l'index dans Elasticsearch selon vos paramètres de configuration.Cette commande indexe toutes les données existantes de votre base de données dans Elasticsearch.

⚠️ Attention : La première indexation peut être longue si vous avez beaucoup de données. Testez d'abord avec un petit dataset pour évaluer le temps nécessaire.

✅ Conseil : Après une indexation, vérifiez toujours que vos données sont bien indexées en lançant quelques requêtes de test.



Utiliser Elasticsearch en pratique

Injection du Finder

Pour utiliser Elasticsearch dans vos contrôleurs, injectez le Finder correspondant :

use FOS\ElasticaBundle\Finder\PaginatedFinderInterface;
use Symfony\Component\DependencyInjection\Attribute\Autowire;

class TrainingElasticSearchQuery extends Query
{
     public function __construct(
         #[Autowire(service: 'fos_elastica.finder.training')]
         private readonly PaginatedFinderInterface $find,
     ) {
         parent::__construct();
     }
}


Recherche simple

Voici un exemple de recherche simple avec MultiMatch sur plusieurs champs :

public function search(array $search, int $page = 0, int $size = 10): PartialResultsInterface
{
     $boolQuery = new BoolQuery();
     $boolQuery->addMust(
         $this->makeSimpleSearch(
             $search['keywords'],
              ['name', 'completeName', 'institution.name']
         )
     );
     
     $this->setQuery($boolQuery);
     return $this->find->createPaginatorAdapter($this)->getResults($page, $size);
}


Recherche avancée avec plage de dates

Pour les recherches plus complexes, combinez plusieurs types de requêtes :

protected function makeRangeBetweenQuery(
     string|int|float $value,
      string $startField,
      string $endField
): BoolQuery
{
     $bool = new BoolQuery();
     $rangeStart = new Range($startField, ['lte' => $value]);
     $rangeEnd = new Range($endField, ['gte' => $value]);


     $bool->addMust($rangeStart);
     $bool->addMust($rangeEnd);

     return $bool;
}

? Conseil : Utilisez les BoolQuery pour combiner plusieurs conditions. addMust() pour les conditions obligatoires, addShould() pour les optionnelles.



Bonnes pratiques et pièges à éviter


✅  Ne pas répliquer la base SQL

Indexez seulement ce qui sert à la recherche. Par exemple, vous n'avez généralement pas besoin d'indexer les clés étrangères ou les champs purement administratifs.


✅  Limiter le nombre de shards et replicas

Trop de shards créent un overhead inutile et dégradent les performances. Trop peu ralentit les recherches. Testez pour trouver le juste équilibre pour votre cas d'usage.

✅  Utiliser des analyzers adaptés

Par exemple, utilisez l'analyzer french pour gérer les accents et le stemming français. Cela améliore significativement la pertinence des résultats.

✅  Maintenir une synchronisation propre

Utilisez les listeners Elasticsearch pour maintenir vos index à jour avec les données de votre BDD. C'est plus fiable que les mises à jour manuelles.


⚠️  Toujours tester vos mappings

Testez avec des échantillons réalistes avant de déployer en production. Changer un mapping après indexation est coûteux.


⚠️  Attention aux insertions massives

Les listeners Elasticsearch peuvent ralentir les insertions massives. Envisagez de les désactiver temporairement pendant ces opérations.


⚠️  Monitorer vos ressources

Elasticsearch est gourmand en mémoire et CPU. Assurez-vous d'allouer suffisamment de ressources et de monitorer votre cluster.