Implémentation de l'Autocomplétion avec Analyseur Pinyin dans Elasticsearch

Lors de la conception de systèmes de recherche, l'autocomplétion prédictive représente une fonctionnalité essentielle. Cette fonctionnalité nécessite l'utilisation du mécanisme Suggest d'Elasticsearch pour identifier les termes correspondant au début de la saisie utilisateur. Un défi supplémentaire apparaît lorsque les requêtes sont formulées en pinyin ou en acronymes, comme la recherche de "téléphone Huawei" via "ths" ou "hw". Cette analyse technique décrit la configuration d'un analyseur pinyin personnalisé et l'implémentation efficace de l'autocomplétion.

Configuration de l'analyseur pinyin

L'extension officielle elasticsearch-analysis-pinyin doit être compilée spécifiquement pour correspondre à la version d'Elasticsearch déployée. Pour une instance fonctionnant sous 8.10.0 :

  1. Télécharger les sources depuis le dépôt officiel
  2. Adapter la dépendance Maven dans le fichier pom.xml :
<properties>
    <elasticsearch.version>8.10.0</elasticsearch.version>
</properties>

Après compilation via Maven (mvn clean package), le package généré se trouve dans target/releases. Déployer le contenu dans le répertoire plugins/pinyin_fr du cluster, puis redémarrer les nœuds. Une validation s'impose via l'API de test :

POST /_analyze
{
  "text": "Shanghai",
  "analyzer": "pinyin"
}

Une réponse valide doit produire des tokens combinant initiales et pinyin :

{
  "tokens": [
    {"token": "sh", "position": 0},
    {"token": "shanghai", "position": 1}
  ]
}

Implémentation de l'autocomplétion

Le champ dédié à l'autocomplétion doit impérativement utiliser le type completion. Voici la configuration d'index optimisée :

PUT /hotels_fr
{
  "settings": {
    "analysis": {
      "analyzer": {
        "recherche_analyseur": {
          "tokenizer": "ik_smart",
          "filter": ["lowercase", "pinyin_fr"]
        },
        "autocompletion_analyseur": {
          "tokenizer": "keyword",
          "filter": ["pinyin_fr"]
        }
      },
      "filter": {
        "pinyin_fr": {
          "type": "pinyin",
          "keep_first_letter": true,
          "keep_separate_first_letter": false,
          "limit_first_letter_length": 16
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "nom": { "type": "text" },
      "marque": { "type": "keyword" },
      "autocomplete_terms": {
        "type": "completion",
        "analyzer": "autocompletion_analyseur"
      }
    }
  }
}

Intégration avec Spring Data Elasticsearch

Voici une implémentation Java modifiée avec des noms de variables et une structure logique renouvelés :

public class AutocompleteDemo {

    @Autowired
    private ElasticsearchOperations elasticsearchOperations;

    public List<String> rechercherSuggestions(String prefix) {
        CompletionSuggestionBuilder suggestion = SuggestBuilders
            .completionSuggestion("autocomplete_terms")
            .prefix(prefix, Fuzziness.AUTO)
            .skipDuplicates(true)
            .size(8);

        SuggestBuilder suggestBuilder = new SuggestBuilder()
            .addSuggestion("resultats", suggestion);

        NativeSearchQuery query = new NativeSearchQueryBuilder()
            .withSuggestBuilder(suggestBuilder)
            .build();

        SearchHits<HotelDocument> hits = elasticsearchOperations
            .search(query, HotelDocument.class);

        return hits.getSuggest().getSuggestion("resultats").getEntries().stream()
            .flatMap(entry -> entry.getOptions().stream())
            .map(option -> option.getHit().getContent().getText())
            .collect(Collectors.toList());
    }
}

Lors de l'indexation, le champ autocomplete_terms doit recevoir un tableau contenant à la fois les noms complets et leurs équivalents en pinyin :

{
  "nom": "Hôtel de la Paix",
  "marque": "Accor",
  "autocomplete_terms": ["Hôtel de la Paix", "hdpl", "hotel de la paix"]
}

Cette configuration permet de répondre à des requêtes comme "hdpl" ou "hotel" avec des suggestions pertinentes, tout en gérant correctement les caractères chinois via leur transcription pinyin.

Étiquettes: elasticsearch-plugins autocomplete-implementation chinese-text-processing spring-data-elasticsearch

Publié le 8 août à 08h27