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.