Guide pour Elasticsearch en Java

Guide de Elasticsearch en Java

1. Vue d'ensemble

Dans cet article, nous allons nous plonger dans certains concepts clés liés aux moteurs de recherche en texte intégral, avec un accent particulier sur Elasticsearch.

Comme il s'agit d'un article orienté Java, nous n'allons pas donner un tutoriel détaillé étape par étape sur la façon de configurer Elasticsearch et montrer comment cela fonctionne sous le capot, nous allons plutôt cibler le client Java, et comment utiliser les principales fonctionnalités telles queindex,delete,get etsearch.

2. Installer

Pour installer Elasticsearch sur votre machine, veuillez vous référer auxofficial setup guide.

Le processus d'installation est assez simple, il suffit de télécharger le package zip / tar et d'exécuter le fichier de scriptelasticsearch (elasticsearch.bat pour les utilisateurs Windows).

Par défaut, Elasticsearch écoute le port 9200 pour les requêtes HTTP à venir par défaut. Nous pouvons vérifier qu'il a été lancé avec succès en ouvrant l'URL dehttp://localhost:9200/ dans votre navigateur préféré:

{
  "name" : "GEpcsab",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "z3FfAe6gRMmSmeWBIOihJg",
  "version" : {
    "number" : "5.6.10",
    "build_hash" : "b727a60",
    "build_date" : "2018-06-06T15:48:34.860Z",
    "build_snapshot" : false,
    "lucene_version" : "6.6.1"
  },
  "tagline" : "You Know, for Search"
}

3. Configuration Maven

Maintenant que notre cluster Elasticsearch de base est opérationnel, passons directement au client Java. Tout d'abord, nous devons avoir lesMaven dependency suivants déclarés dans notre fichierpom.xml:


    org.elasticsearch
    elasticsearch
    5.6.0

Vous pouvez toujours consulter les dernières versions hébergées par Maven Central à l'aide du lien fourni auparavant.

4. API Java

Avant de passer directement à l'utilisation des principales fonctionnalités de l'API Java, nous devons lancer le client de transport:

Client client = new PreBuiltTransportClient(
  Settings.builder().put("client.transport.sniff", true)
                    .put("cluster.name","elasticsearch").build())
  .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));

4.1. Indexation de documents

La fonctionprepareIndex() permet de stocker un document JSON arbitraire et de le rendre interrogeable:

@Test
public void givenJsonString_whenJavaObject_thenIndexDocument() {
    String jsonObject = "{\"age\":10,\"dateOfBirth\":1471466076564,"
      +"\"fullName\":\"John Doe\"}";
    IndexResponse response = client.prepareIndex("people", "Doe")
      .setSource(jsonObject, XContentType.JSON).get();

    String id = response.getId();
    String index = response.getIndex();
    String type = response.getType();
    long version = response.getVersion();

    assertEquals(Result.CREATED, response.getResult());
    assertEquals(0, version);
    assertEquals("people", index);
    assertEquals("Doe", type);
}

Lors de l'exécution du test, assurez-vous de déclarer la variablepath.home, sinon l'exception suivante peut apparaître:

java.lang.IllegalStateException: path.home is not configured

Après avoir exécuté la commande Maven:mvn clean install -Des.path.home=C:\elastic, le document JSON sera stocké avecpeople comme index etDoe comme type.

Notez qu'il est possible d'utiliserany JSON Java library pour créer et traiter vos documents. If you are not familiar with any of these, you can use Elasticsearch helpers to generate your own JSON documents:

XContentBuilder builder = XContentFactory.jsonBuilder()
  .startObject()
  .field("fullName", "Test")
  .field("dateOfBirth", new Date())
  .field("age", "10")
  .endObject();
IndexResponse response = client.prepareIndex("people", "Doe")
  .setSource(builder).get();

assertEquals(Result.CREATED, response.getResult());

4.2. Interroger des documents indexés

Maintenant que nous avons un document JSON de recherche typé indexé, nous pouvons continuer et rechercher en utilisant la méthodeprepareSearch():

SearchResponse response = client.prepareSearch().execute().actionGet();
List searchHits = Arrays.asList(response.getHits().getHits());
List results = new ArrayList();
searchHits.forEach(
  hit -> results.add(JSON.parseObject(hit.getSourceAsString(), Person.class)));

The results returned by the actionGet() method are called Hits, chaqueHit fait référence à un document JSON correspondant à une demande de recherche.

Dans ce cas, la listeresults contient toutes les données stockées dans le cluster. Notez que dans cet exemple, nous utilisons la bibliothèqueFastJson afin de convertir les JSONStrings en objets Java.

Nous pouvons améliorer la requête en ajoutant des paramètres supplémentaires afin de personnaliser la requête en utilisant les méthodesQueryBuilders:

SearchResponse response = client.prepareSearch()
  .setTypes()
  .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
  .setPostFilter(QueryBuilders.rangeQuery("age").from(5).to(15))
  .execute()
  .actionGet();

4.3. Récupération et suppression de documents

Les méthodesprepareGet() etprepareDelete() permettent d'obtenir ou de supprimer un document JSON du cluster en utilisant son id:

GetResponse response = client.prepareGet("people","Doe","1").get();
String age = (String) response.getField("age").getValue();
// Process other fields
DeleteResponse response = client.prepareDelete("people", "Doe", "5")
  .get();

La syntaxe est assez simple, il vous suffit de spécifier l'index et la valeur du type à côté de l'ID de l'objet.

5. Exemples deQueryBuilders

La classeQueryBuilders fournit une variété de méthodes statiques utilisées comme correspondants dynamiques pour rechercher des entrées spécifiques dans le cluster. Lors de l'utilisation de la méthodeprepareSearch() pour rechercher des documents JSON spécifiques dans le cluster, nous pouvons utiliser des générateurs de requêtes pour personnaliser les résultats de la recherche.

Voici une liste des utilisations les plus courantes de l'APIQueryBuilders.

La méthodematchAllQuery() renvoie un objetQueryBuilder qui correspond à tous les documents du cluster:

QueryBuilder matchAllQuery = QueryBuilders.matchAllQuery();

LerangeQuery() correspond aux documents où la valeur d'un champ se situe dans une certaine plage:

QueryBuilder matchDocumentsWithinRange = QueryBuilders
  .rangeQuery("price").from(15).to(100)

Fournir un nom de champ - par exemple fullName et la valeur correspondante - par ex. John Doe, la méthodematchQuery() correspond à tous les documents avec la valeur exacte de ces champs:

QueryBuilder matchSpecificFieldQuery= QueryBuilders
  .matchQuery("fullName", "John Doe");

Nous pouvons également utiliser la méthodemultiMatchQuery() pour construire une version multi-champs de la requête de correspondance:

QueryBuilder matchSpecificFieldQuery= QueryBuilders.matchQuery(
  "Text I am looking for", "field_1", "field_2^3", "*_field_wildcard");

We can use the caret symbol (^) to boost specific fields.

Dans notre exemple,field_2 a une valeur de boost définie sur trois, ce qui la rend plus importante que les autres champs. Notez qu'il est possible d'utiliser des caractères génériques et des requêtes regex, mais en termes de performances, méfiez-vous de la consommation de mémoire et du délai de réponse lorsque vous traitez avec des caractères génériques, car quelque chose comme * _apples peut avoir un impact considérable sur les performances.

Le coefficient d'importance est utilisé pour classer l'ensemble de résultats des hits renvoyés après l'exécution de la méthodeprepareSearch().

Si vous êtes plus familier avec la syntaxe des requêtes Lucene, vous pouvez utiliser lessimpleQueryStringQuery() method to customize search queries:

QueryBuilder simpleStringQuery = QueryBuilders
  .simpleQueryStringQuery("+John -Doe OR Janette");

Comme vous pouvez probablement le deviner,we can use the Lucene’s Query Parser syntax to build simple, yet powerful queries. Voici quelques opérateurs de base qui peuvent être utilisés avec les opérateursAND/OR/NOT pour créer des requêtes de recherche:

  • L'opérateur requis (+): nécessite qu'un morceau de texte spécifique existe quelque part dans les champs d'un document.

  • L'opérateur d'interdiction (): exclut tous les documents contenant un mot-clé déclaré après le symbole ().

6. Conclusion

Dans cet article rapide, nous avons vu comment utiliser l'API Java d'ElasticSearch pour exécuter certaines des fonctionnalités courantes liées aux moteurs de recherche en texte intégral.

Vous pouvez consulter l'exemple fourni dans cet article dans leGitHub project.