[JAVA] Migrer du client de transport vers le client de niveau supérieur Rest

introduction

Cet article est l'article du 18e jour du Calendrier de l'Avent Elastic stack (Elasticsearch) 2018.

Lorsque je suis devenu ingénieur d'applications Web et que j'ai été chargé de mettre en œuvre pour la première fois la recherche en texte intégral à l'aide de la recherche élastique sur le terrain J'ai eu du mal avec un article utilisant JavaClient, donc j'espère qu'il sera utile pour ces personnes.

Contenu de l'article

En supposant que l'application Spring intègre la fonction de recherche en texte intégral à l'aide de JavaClient. Non recommandé de la série Elasticsearch 7, le client de transport aurait complètement disparu de la série 8 J'ai résumé les changements dans la connexion client et la génération de requêtes lors de la migration vers RestHighLevelClient.

Cette fois, les connexions comprenant l'authentification, l'API Bulk et l'API de défilement ne sont pas couvertes.

environnement

macOS Elasticsearch6.5.2 Java8 Spring Boot 2.1.1

Préparation

Exemple d'application

L'application que j'ai créée est répertoriée sur GitHub. https://github.com/ohanamisan/Elasticsearch_on_Java

Si la version d'Elasticsearch est différente, modifiez l'emplacement d'importation du fichier JAR du fichier gradle selon vos besoins. À propos, dans l'exemple, le processus d'insertion avec Bulk est également implémenté à peu près. Aucun détail n'est donné dans cet article. Pour plus de détails, veuillez consulter LISEZ-MOI

la mise en oeuvre

TransportClient -> RestHighLevelClient Immédiatement, c'est la migration du client leader.


TransportClient client = new PreBuiltTransportClient(Settings.EMPTY)
        .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9300));

Le client de transport, qui a été utilisé comme standard jusqu'à présent, ressemble à ceci. Le numéro de port est 9300, qui est fourni en tant que Transport au lieu de la valeur par défaut d'Elasticsearch, 9200.

Au fait, voici la version α de la série 7. transport非推奨.png

Il est obsolète. Il ne peut pas être utilisé à partir de la série 8.

Maintenant, réécrivons-le en RestHighLevelClient, qui sera la norme à l'avenir.


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

Avez-vous envie de frapper directement le 9200 avec un accès http sans utiliser le 9300 pour le transport? Je pense que c'est. Le nom et la structure sont si simples que vous pouvez voir que vous appuyez sur Reste en un coup d'œil.

Lorsque vous utilisez plusieurs Elasticsearch sur le même serveur, le port utilisera automatiquement le port suivant, ajoutez donc des HttpHosts séparés par des virgules en fonction du nombre.


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

TransportClient crachait des journaux qui allaient accéder en interne avec netty, mais RestHighLevelClient ne génère pas de journaux par défaut probablement parce qu'il frappe avec Rest comme son nom l'indique.

prepareSearch -> SearchSourceBuilder + SearchRequest Ensuite, nous modifierons l'implémentation de la génération de requête. La requête générée lors de la recherche en texte intégral cette fois est supposée être la suivante.


{
  "query": {
    "bool": {
      "should": [
        {
          "match_phrase": {
            "title.full_text_search":Rechercher un mot
          }
        },
        {
          "match_phrase": {
            "body.full_text_search":Rechercher un mot
          }
        }
      ], "minimum_should_match": 1
    }
  }
}

Une requête simple qui lance une requête match_phrase sur le texte et le titre. Je voulais faire une recherche en texte intégral qui incluait le titre, donc si j'utilisais une requête should et frappais soit le titre soit le corps, ce serait positif.

Nous allons générer cette requête en Java.

La génération et la demande de requête lors de l'utilisation de TransportClient sont les suivantes.


BoolQueryBuilder query = QueryBuilders.boolQuery();		
query.should(QueryBuilders.matchPhraseQuery("title.full_text_search", word))
  .should(QueryBuilders.matchPhraseQuery("body.full_text_search", word));
  .minimumShouldMatch(1));
SearchResponse res = client.prepareSearch("qiita")
				.setQuery(query)
				.setSize(1000)
				.get();
res.getHits();

Générer une requête avec QueryBuilders et utiliser la méthode prepareSearch du client Je transmettrai la requête de demande et les paramètres au moment de la demande.

En passant, même en Java, si vous imbriquez des générateurs de requêtes ou des méthodes de chaîne, vous pouvez générer des requêtes assez compliquées ainsi que des requêtes en JSON.

RestHighLevelClient n'a plus de méthode prepareSearch La méthode de recherche avec SearchRequest comme argument est utilisée. Voici le code modifié.


SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.from(0);
sourceBuilder.size(1000);
sourceBuilder.query(QueryBuilders.boolQuery()
                    .should(QueryBuilders.matchPhraseQuery("title.full_text_search", word))
                    .should(QueryBuilders.matchPhraseQuery("body.full_text_search", word))
                    .minimumShouldMatch(1));

SearchRequest req = new SearchRequest().indices(INDEX).source(sourceBuilder);

SearchResponse res = client.search(req, RequestOptions.DEFAULT);
res.getHits();

Je pense que le nombre de lignes de code est devenu long, J'ai l'impression que les responsabilités de définition des requêtes, des requêtes et des réponses sont séparées, ce qui facilite la gestion personnelle.

Courir

Qiita全文検索.gif

Je suis désolé d'avoir épuisé mes efforts pour créer des gifs, mais j'espère que vous pouvez voir que le mot de recherche "Java" n'est pas inclus dans le titre. Cela ressemble à un succès du texte.

Résumé

Cette fois, j'ai essayé d'implémenter la recherche minimale en texte intégral dans l'environnement local à titre d'exemple.

RestHighLevelClient avec authentification de base lorsque xpack etc. est inséré Comme il existe encore des éléments d'extension tels que l'API Scroll pour la pagination qui sont indispensables pour la recherche Prenant ce premier post (en fait) comme une opportunité, j'aimerais continuer à écrire des articles tout en élargissant l'échantillon.

De plus, comme j'ai implémenté Java après une longue période, veuillez signaler tout point étrange.

à la fin

Demain aura lieu la 27ème session d'étude sur la recherche élastique "LT & fête de fin d'année"! https://www.meetup.com/ja-JP/Tokyo-Elastic-Fantastics/events/256619262/

Recommended Posts

Migrer du client de transport vers le client de niveau supérieur Rest
Conseils pour le client REST de haut niveau Java
Arrêter de renvoyer du client au serveur
Migrer de on-prepukiwiki vers esa.io \ (⁰⊖⁰) /
Migrer de Java vers Kotlin côté serveur + Spring-boot
[Swift, ARKit] Migrer de hitTest obsolète vers raycastQuery