Comprendre et utiliser Elasticsearch pour la recherche full-text

Elasticsearch est un moteur de recherche distribué, open source et hautement évolutif, conçu pour traiter efficacement des volumes massifs de données non structurées ou semi-structurées. Il fait partie de l'écosystème Elastic Stack (ELK), qui inclut également Kibana, Logstash et Beats.

Préparation de l'environnement

Téléchargez Elasticsearch depuis le site officile. Après extraction, lancez le service via bin/elasticsearch (Linux/macOS) ou bin\elasticsearch.bat (Windows). Par défaut, l'API REST est accessible sur http://localhost:9200.

Structure des répertoires principaux :

  • bin/ : scripts exécutables
  • config/ : fichiers de configuration
  • logs/ : journaux d'exécution
  • plugins/ : extensions personnalisées

Concepts fondamentaux

Index et documents

Un index équivaut à une base de données relationnelle, tandis qu’un document correspond à une ligne dans une table. Chaque document est stocké au format JSON.

Inversion d'index

Contrairement aux bases de données traditionnelles qui utilisent des index "directs", Elasticsearch cosntruit un index inversé : chaque mot devient une clé pointant vers les documents qui le contiennent. Cela permet des recherches ultra-rapides même sur des téraoctets de données.

Manipulations de base via API REST

Création d’un index

PUT http://localhost:9200/produits

Réponse :

{
  "acknowledged": true,
  "index": "produits"
}

Ajout d’un document

POST http://localhost:9200/produits/_doc
{
  "nom": "iPhone 15",
  "marque": "Apple",
  "prix": 999.99,
  "description": "Smartphone haut de gamme avec écran OLED."
}

Recherche par identifiant

GET http://localhost:9200/produits/_doc/abc123

Recherche full-text

GET http://localhost:9200/produits/_search
{
  "query": {
    "match": {
      "description": "écran OLED"
    }
  }
}

Suppression logique

DELETE http://localhost:9200/produits/_doc/abc123

Fonctionnalités avancées

Tri et pagination

{
  "query": { "match_all": {} },
  "sort": [{ "prix": { "order": "desc" } }],
  "from": 0,
  "size": 10
}

Requêtes booléennes

{
  "query": {
    "bool": {
      "must": [
        { "match": { "marque": "Apple" } },
        { "range": { "prix": { "lt": 1000 } } }
      ]
    }
  }
}

Agrégations (analytics)

{
  "aggs": {
    "prix_moyen_par_marque": {
      "terms": { "field": "marque.keyword" },
      "aggs": {
        "moyenne": { "avg": { "field": "prix" } }
      }
    }
  },
  "size": 0
}

Mise en surbrillance

{
  "query": { "match": { "description": "OLED" } },
  "highlight": {
    "fields": { "description": {} }
  }
}

Utilisation en Java

Ajoutez les dépnedances Maven :

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.17.0</version>
</dependency>

Exemple de connexion et requête :

RestHighLevelClient client = new RestHighLevelClient(
    RestClient.builder(new HttpHost("localhost", 9200, "http"))
);

SearchRequest searchReq = new SearchRequest("produits");
SearchSourceBuilder srcBuilder = new SearchSourceBuilder();
srcBuilder.query(QueryBuilders.matchQuery("marque", "Samsung"));
searchReq.source(srcBuilder);

SearchResponse response = client.search(searchReq, RequestOptions.DEFAULT);
for (SearchHit hit : response.getHits()) {
    System.out.println(hit.getSourceAsString());
}

client.close();

Mapping personnalisé

Définissez explicitement la structure des champs pour optimiser les performances :

PUT /produits/_mapping
{
  "properties": {
    "nom": { "type": "text" },
    "marque": { "type": "keyword" },
    "prix": { "type": "float" },
    "date_sortie": { "type": "date" }
  }
}

Utilisez text pour les recherches full-text, keyword pour les filtres exacts, et désactivez l'indexation ("index": false) pour les champs non recherchables.

Étiquettes: Elasticsearch rest-api java-client full-text-search aggregations

Publié le 22 août à 13h35