【Elasticsearch 6.5】Rest Client方式集積SpringBoot応用


引用する
前回のブログでは、Elasticsearch操作インデックスAPIを簡単に適用し、Headプラグインの下でESに格納されているインデックスデータ構造を見ました.この記事では、SpringBootアプリケーションでElasticsearchを統合し、コードによってインデックスの一連の操作を完了する方法を説明します.
統合方式
Spring Bootアプリケーション統合Elasticsearchには、SpringBootが公式に提供しているstarterを直接参照し、hibernate JPA仕様を通じてdao層がElasticsearchRepositoryを継承するなど、さまざまな方法があります.これはインデックス・データベースの操作に相当します.この方法の利点は、統合が容易で、簡単で便利であるが、欠点は柔軟ではないことであり、パッケージされた方法しか使用できず、いくつかのElasticsearchの複雑なクエリーでは実現できない.
そのため、一般的にはElasticsearchのいくつかのAPIを自分で操作したいと思っています.私たちが最も使用している統合方法は、Elasticsearchが提供するClientを直接使用して操作することです.
Elasticsearchが提供するクライアントドッキング方式もREST APIとTransportの2種類に分けられる.REST APIはHTTP接続方式を使用し、ポート番号は9200で、RESTスタイルのAPIを提供している.Transport方式はTCP接続方式を用い,ポート番号は9300であり,ESを直接接続するノードである.ESのバージョンが更新されるにつれて、ES 7.0はTransportを閉じ、8.0は完全に削除され、代わりにHigh Level REST Clientになります.
公式に推奨されているのもRest Client方式で接続統合されています.
統合環境
• Spring Boot : 2.1.3.RELEASE
• Elastic Search Client:6.5.4
統合手順
1.Maven依存の導入
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
<!--     -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.8.1</version>
</dependency>
<!-- Java Low Level REST Client -->
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-client</artifactId>
    <version>6.5.4</version>
</dependency>
<!-- Java High Level REST Client -->
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>6.5.4</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.69</version>
</dependency>

2.インスタンス化Rest Client
private RestHighLevelClient client;
/**
 * Java High Level REST Client     
 */
public EsClient() {
     
    client = new RestHighLevelClient(
            RestClient.builder(
                    new HttpHost("192.168.17.146", 9200, "http")));
}

以下に、インデックスを操作するツールクラスのコアコードのみを示します.パラメータの構造はサービス層で処理され、完全なプロジェクトインスタンスコードは、文章の最後のgithubリンクアドレスでダウンロードできます.
3.インデックスとドキュメントの追加
/**
 *   ,    
 *
 * @param indexName   
 * @param type      mapping type
 * @param id          id
 * @param jsonStr       
 */
public IndexResponse addData(String indexName, String type, String id, String jsonStr) {
     
    IndexResponse indexResponse = null;
    try {
     
        // 1、        //    // mapping type  //  id
        IndexRequest request = new IndexRequest(indexName, type, id);
        // 2、      
        //    JSON 
        request.source(jsonStr, XContentType.JSON);
        //4、    
        try {
     
            //     
            indexResponse = client.index(request, RequestOptions.DEFAULT);
        } catch (ElasticsearchException e) {
     
            //   ,     
            //        、create        
            if (e.status() == RestStatus.CONFLICT) {
     
                log.error("[ESUtil.addData] [error] [conflict]", e);
            }
        }
        //5、    
        if (indexResponse != null) {
     
            String index1 = indexResponse.getIndex();
            String type1 = indexResponse.getType();
            String id1 = indexResponse.getId();
            long version1 = indexResponse.getVersion();
            if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {
     
                log.info("[ESUtil.addData] [end] [create success] [result is {}]", index1 + type1 + id1 + version1);
            } else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {
     
                log.info("[ESUtil.addData] [end] [update success]");
            }
            //       
            ReplicationResponse.ShardInfo shardInfo = indexResponse.getShardInfo();
            if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
     
                log.info("[ESUtil.addData] [start] [sharding info]");
            }
            //          ,          
            if (shardInfo.getFailed() > 0) {
     
                for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
     
                    String reason = failure.reason();
                    log.error("[ESUtil.addData] [error] [replicate failure, reason is {}]", reason);
                }
            }
            return indexResponse;
        }
    } catch (Exception e) {
     
        log.error("[ESUtil.addData] [error] [fail to add data]", e);
    }
    return indexResponse;
}

4.指定したインデックスのすべてのデータを問い合わせる
/**
 *         
 *
 * @param request
 * @return
 */
public GetResponse queryOne(GetRequest request) {
     
    GetResponse documentFields = null;
    try {
     
        documentFields = client.get(request, RequestOptions.DEFAULT);
    } catch (IOException e) {
     
        log.error("[ESUtil.queryOne] [error] [fail to query one, param is {}]", JSON.toJSON(request), e);
    }
    return documentFields;
}   

5.条件クエリーインデックスデータ
/**
 *       
 *
 * @param request
 * @return
 */
public Map<String, Object> queryAll(SearchRequest request) {
     
    Map<String, Object> resultMap = new HashMap<>(10);
    SearchResponse response;
    try {
     
        response = client.search(request, RequestOptions.DEFAULT);
        //            
        SearchHits searchHits = response.getHits();
        //        
        long total = searchHits.getTotalHits();
        resultMap.put("total", total);
        resultMap.put("tookInMillis", response.getTook().getMillis());
        //          map
        if (total > 0) {
     
            SearchHit[] searchHitsArr = searchHits.getHits();
            List<Map<String, Object>> resultMapList = convertResultToObject(searchHitsArr);
            resultMap.put("list", resultMapList);
        }
    } catch (IOException e) {
     
        log.error("[ESUtil.queryAll] [error] [fail to query, param is {}]", JSON.toJSON(request), e);
        return resultMap;
    }
    return resultMap;
}

//       ES               
/**
 * ES         
 *
 * @param searchHitsArr
 * @return
 */
private List<Map<String, Object>> convertResultToObject(SearchHit[] searchHitsArr) {
     
    List<Map<String, Object>> resultMapList = new ArrayList<>(searchHitsArr.length);
    for (SearchHit documentFields : searchHitsArr) {
     
        Map<String, Object> map = documentFields.getSourceAsMap();
        resultMapList.add(map);
    }
    return resultMapList;
}

まとめ
この文書のサンプルコードはgithub:SpringBoot-elasticsearch 6.5にアップロードされており、EsClientのESサービスのipを自分で利用できるものに変更するだけでインデックスを操作することができ、前期の学習と熟知を容易にすることができます.本番プロジェクトでは、ノード構成の読み取り、リクエストヘッダの設定、タイムアウト時間の設定など、さらに最適化し、その後の更新が必要です.