Springboot整合RestHighLevelClient進行Elasticsearch操作,基於6.3.2版本,6.1.1測試通過(辛酸踩坑歷史及經驗分享)

說一下寫這篇文章的原因,有點小複雜。

1.公司的es版本是6.1.1.禁用了9300的transport端口,只開放了rest端口. 我的springboot項目版本是2.2.0.

2.一開始興致勃勃使用了springdata starter es,覺得就這麼完事了。跑起來完全不報錯,結果一來個簡單查詢就給我報錯了,報的是查詢參數多了,es當前版本並不支持該參數,不就是http請求嗎?多傳個參數你就掛了....

3.然後開始看springboot starter如何使用6.1.1的es,結果需要降springboot版本到2.0,我降了。然而發現6.1.1版本整合的是transportclient,需要開放transport端口,然而公司這個端口已被禁用,小開發,管不了。無疾而終。

4.於是發現了jest的一個項目,可以將9200僞裝成一個es node節點,從而整合springdata es,於是使用9200接入了需要9300端口的spring data es,至此6.1.1的es整合就結束了,已經讓我可以對es進行一些操作了。

5.然而這就完事了嗎?我發現我太天真了。spring data es對映射實體限制的很死。我們的表索引名是存放在某張表裏的,這張表每15分鐘更新一次,我需要從這張表獲取真實的索引表,再去查該索引表的數據。我發現es完全實現不了。

6.由於該需求,我發現es完全滿足不了我的需求。又害我白白降了springboot版本。於是我決定不用它了。自己使用RestHighLevelClient對es進行定製化操作。

7.新的坑又來啦,springdata es在6.1.1使用transport連接es是有原因的:官方sdk並不完善,連創建索引的api都沒有。這時候我試着去看更高版本的resthighlevelclient,發現6.2.4支持了索引的添加,但是又不支持mapping和setting的修改。我又往6.3.2的sdk看了一下,發現該sdk才支持這兩個修改。

8.於是我小心翼翼的把sdk版本升到6.3.2,然後來操作我6.1.1的es.萬幸!!!所有我需要使用的操作,都測試通過,完美!!!踩坑結束。

9.最後發現最高只能升到6.3.再往後就不支持了,能用就用吧,話說如果有同樣使用低版本的es使用者,有新坑希望可以一起交流交流。

 

總結一下我的踩坑經驗:

1.千萬不要用低版本的es,有坑,有巨坑!!!

2.如果非要用,最好用spring data es支持restclient連接的版本,注意版本和spring boot的適配。然而正常人不可能因爲一個es就換springboot版本,升級或者降級,如果你不想升降級springboot,那就用官方sdk ->resthighlevelclient,不就自己封裝一下,也沒有多難,對不對?spring data starter es和es還有springboot真的是強版本關聯,真的太坑了。

3.關於sdk的問題,sdk隨着版本升級,每次升級越來越完善,低版本的sdk簡直簡陋到不要不要的。如果你當前的操作sdk不支持,試着去看高版本的sdk的api,實現完之後,記得寫測試用例測多幾遍,因爲有版本兼容問題,官網描述的,像我就把自己所有的操作都寫了單元測試,升級完sdk,就每個都走一遍,全部通過就升,不解釋。

4.spring data es真的有毒,很多侷限,巨多侷限,如果你要進行索引表的增刪改查,使用RestHighLevelClient吧!,如果兩者都要用,那就用spring data es,從bean Factory中獲取對象操作吧。相信我,你會有很多增刪改查索引表的場景的。

5.在準備使用get index api的時候,發現6.3.2客戶端不支持,需要升級到6.4.3. 經測試,6.1.1的es最多隻能使用6.3.2的客戶端。升級到6.4.3版本客戶端失敗,問題出在RequestConverter,該類在參數裏面放置了masterTimeout,導致請求不適配,除非重寫把該類和包名完整拷貝出來,刪除多餘的參數,覆蓋(重寫)這個類。但是感覺沒有必要,es一升級,這個類可能又得重新改,極其麻煩。這時候發現了低level的client的作用了,我們可以使用RestClient自定義實現該功能。這個restClient可以完全自己定義。不過實現高級的功能也許有點麻煩,這裏只是簡單實現get index api就行了。在通用template有示例代碼。

廢話不多說了,下面是整合的記錄。

一.maven配置

<properties>
		<elasticsearch.version>6.3.2</elasticsearch.version>
</properties>
<dependencies>
        <dependency>
			<groupId>org.elasticsearch</groupId>
			<artifactId>elasticsearch</artifactId>
			<version>${elasticsearch.version}</version>
		</dependency>
		<dependency>
			<groupId>org.elasticsearch.client</groupId>
			<artifactId>elasticsearch-rest-client</artifactId>
			<version>${elasticsearch.version}</version>
		</dependency>
		<dependency>
			<groupId>org.elasticsearch.client</groupId>
			<artifactId>elasticsearch-rest-high-level-client</artifactId>
			<version>${elasticsearch.version}</version>
		</dependency>
<dependencies>

二.配置類

package com.mytest.test.config;

import org.apache.commons.lang3.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

/**
 * ElasticsearchConfig
 *
 * @author lxx
 * @date 2019/11/11
 */
@Configuration
@Slf4j
public class ElasticsearchConfig implements FactoryBean<RestHighLevelClient>, InitializingBean, DisposableBean {

    @Value("${mytest.elasticsearch.rest.uri}")
    private String uri;

    //Java Low Level REST Client (要想使用高版本client必須依賴低版本的client)
    private RestClient client;
    //Java High Level REST Client (高版本client)
    private RestHighLevelClient restHighLevelClient;

    //初始化client
    protected void initClient() {
        if(StringUtils.isEmpty(uri)){
            throw new RuntimeException("elasticsearch uri is unset to properties file");
        }
        String [] nodes = uri.split(",");
        HttpHost [] httpHosts = new HttpHost[nodes.length];
        for(int x = 0;x<nodes.length;x++){
            String [] uris = nodes[x].split(":");
            HttpHost httpHost = new HttpHost(uris[0],Integer.parseInt(uris[1]),"http");
            httpHosts[x] = httpHost;
        }
        RestClientBuilder restClientBuilder = RestClient.builder(httpHosts);
        restClientBuilder.setMaxRetryTimeoutMillis(3500);//設置http客戶請求時長
        restHighLevelClient = new RestHighLevelClient(restClientBuilder);
        client = restHighLevelClient.getLowLevelClient();
//        賬號密碼的方式
//        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
//        credentialsProvider.setCredentials(AuthScope.ANY,
//                new UsernamePasswordCredentials(username, password));
//        client = RestClient.builder(new HttpHost(host, port))
//                .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
//                    @Override
//                    public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
//                        return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
//                    }
//                })
//                .build();
    }

    @Override
    public void destroy() throws Exception {
        try {
            log.info("Closing elasticSearch client");
            if (client != null) {
                client.close();
            }
        } catch (final Exception e) {
            log.error("Error closing ElasticSearch client: ", e);
        }
    }

    @Override
    public RestHighLevelClient getObject() throws Exception {
        return restHighLevelClient;
    }

    @Override
    public Class<RestHighLevelClient> getObjectType() {
        return RestHighLevelClient.class;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        initClient();
    }
}

三.相關properties配置

mytest.elasticsearch.rest.uri=192.168.1.1:9200

四.我的elasticsearch工具類,提供簡單es的增刪改查的封裝,在自己的業務中只需要注入該類進行操作即可。

根據官方api的陳述,低版本的highlevelclient完全可以操作高版本的es,例如我使用6.3.2版本的sdk,是支持6.3.2+的es的。

但是高版本的highlevelclient不一定全部支持低版本的es。

但是根據測試,使用6.3.2的sdk以下所有的api全部兼容6.1.1版本的es.

如果不放心,可以專門寫一個es的單元測試,把所有的接口都測試一遍,但是自測已經全部通過。

package com.mytest.test.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.action.DocWriteRequest;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsResponse;
import org.elasticsearch.action.bulk.BulkItemResponse;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.*;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * AmElasticsearchTemplate
 * 使用6.3.2的api,以下接口都支持6.1.1的es,如果新增其他接口,請自行測試
 *
 * @author lxx
 * @date 2019/11/11
 */
@Service
@Slf4j
public class AmElasticsearchTemplate {

    @Resource
    private RestHighLevelClient restHighLevelClient;

    private static final String TYPE = "type";

    /**
     * 查詢某個索引的數據
     *
     * @date 2019/12/12
     * @param indexName 索引名稱
     * @param clazz     返回的數據類型
     * @return java.util.List<T> 返回列表
     */
    public <T> List<T> findIndex(String indexName, Class<T> clazz){
        try {
            SearchRequest searchRequest = new SearchRequest(indexName);
            SearchResponse getResponse = restHighLevelClient.search(searchRequest);
            SearchHits searchHits = getResponse.getHits();
            List<T> results = new ArrayList<>();
            for(SearchHit hit : searchHits){
                T t = JSON.parseObject(hit.getSourceAsString(),clazz);
                results.add(t);
            }
            return results;
        } catch (IOException e) {
            throw new RuntimeException("findIndex Exception",e);
        }
    }

    /**
     * 根據索引獲取是否有該索引,如果通配符,返回通配符適配的多個索引(用來做定時刪除處理,根據通配符獲取多個索引,然後根據備份規則,篩選數據,刪掉必要索引)
     *
     * @date 2019/12/18
     * @param indexName 索引
     * @return java.util.List<java.lang.String>
     */
    public List<String> getIndex(String indexName){
        RestClient restClient = restHighLevelClient.getLowLevelClient();
        try {
            Response response = restClient.performRequest("GET", "/" + indexName);
            String responseBody = EntityUtils.toString(response.getEntity());
            if(!StringUtils.isEmpty(responseBody)){
                JSONObject jsonObject = (JSONObject) JSONObject.parse(responseBody);
                List<String> list = new ArrayList<>(jsonObject.size());
                for(Map.Entry<String,Object> entry : jsonObject.entrySet()){
                    list.add(entry.getKey());
                }
                return list;
            }
            return null;
        } catch (IOException e) {
            if(e instanceof ResponseException){
                int statusCode = ((ResponseException) e).getResponse().getStatusLine().getStatusCode();
                if(statusCode == 404){
                    return null;
                }
            }
            log.error("獲取索引異常",e);
            throw new RuntimeException("獲取索引異常",e);
        }
    }

    /**
     * 根據id獲取索引的數據
     *
     * @date 2019/12/12
     * @param indexNames    索引名稱
     * @param id            id
     * @param clazz         返回的結果類型class
     * @return T            返回對應結果類型的結果
     */
    public <T> T getById(String indexNames, String id,Class<T> clazz) {
         try {
             GetRequest request = new GetRequest(indexNames, TYPE, id);
             GetResponse getReponse = restHighLevelClient.get(request);
             if(getReponse.isExists()) {
                 String result = getReponse.getSourceAsString();
                 T t = JSONObject.parseObject(result,clazz);
                 return t;
             }
         }catch (Exception e){
            throw new RuntimeException("getById exception",e);
         }
         return null;
    }

    /**
     * 根據ids批量獲取數據,默認根據id排序
     *
     * @date 2019/12/12
     * @param indexNames    索引名稱
     * @param clazz         返回類型
     * @param ids           id數組
     * @return java.util.List<T>
     */
    public <T> List<T>  getByIds(String indexNames, Class<T> clazz,String [] ids) {
         try {
             SearchRequest searchRequest = new SearchRequest(indexNames);
             SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
             QueryBuilder queryBuilder = QueryBuilders.idsQuery().addIds(ids);
             sourceBuilder.query(queryBuilder);
             sourceBuilder.size(ids.length);
             //id排序
             sourceBuilder.sort(new FieldSortBuilder("_id"));
             searchRequest.source(sourceBuilder);
             searchRequest.types(TYPE);
             SearchResponse searchResponse = restHighLevelClient.search(searchRequest);
             SearchHits searchHits = searchResponse.getHits();
             List<T> results = new ArrayList<>();
             for(SearchHit hit : searchHits){
                 T t = JSON.parseObject(hit.getSourceAsString(),clazz);
                 results.add(t);
             }
             return results;
         }catch (Exception e){
             throw new RuntimeException("multiGetByIds exception",e);
         }
    }

    /**
     * 根據ids分頁獲取數據
     *
     * @date 2019/12/12
     * @param indexNames    索引名稱
     * @param clazz         類型
     * @param ids           id數組
     * @param startIndex    開始index
     * @param pageSize      每頁顯示多少數據
     * @return java.util.List<T>
     */
    public <T> List<T>  getByIds(String indexNames, Class<T> clazz, String[] ids, int startIndex, int pageSize) {
        try {
            SearchRequest searchRequest = new SearchRequest(indexNames);
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            QueryBuilder queryBuilder = QueryBuilders.idsQuery().addIds(ids);
            sourceBuilder.query(queryBuilder);
            sourceBuilder.from(startIndex);
            sourceBuilder.size(pageSize);
            //id排序
            sourceBuilder.sort(new FieldSortBuilder("_id"));
            searchRequest.source(sourceBuilder);
            searchRequest.types(TYPE);
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest);
            SearchHits searchHits = searchResponse.getHits();
            List<T> results = new ArrayList<>();
            for(SearchHit hit : searchHits){
                T t = JSON.parseObject(hit.getSourceAsString(),clazz);
                results.add(t);
            }
            return results;
        }catch (Exception e){
            throw new RuntimeException("multiGetByIds exception",e);
        }
    }

    /**
     * 排序分頁
     *
     * @date 2019/12/12
     * @param indexNames 索引名稱
     * @param clazz      類型
     * @param sortName   排序名稱
     * @param order      正倒序
     * @param start      開始位置
     * @param size       每頁條數
     * @return java.util.List<T>
     */
    public <T> List<T> findPageBySort(String indexNames, Class<T> clazz,String sortName,SortOrder order, int start, int size) {
        try {
            SearchRequest searchRequest = new SearchRequest(indexNames);
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            sourceBuilder.from(start);
            sourceBuilder.size(size);
            //rank排序
            sourceBuilder.sort(new FieldSortBuilder(sortName).order(order));
            searchRequest.source(sourceBuilder);
            searchRequest.types(TYPE);
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest);
            SearchHits searchHits = searchResponse.getHits();
            List<T> results = new ArrayList<>();
            for(SearchHit hit : searchHits){
                T t = JSON.parseObject(hit.getSourceAsString(),clazz);
                results.add(t);
            }
            return results;
        }catch (Exception e){
            throw new RuntimeException("multiGetByIds exception",e);
        }
    }



    /**
     * 搜索分頁
     *
     * @date 2019/12/12
     * @param indexNames    索引名稱
     * @param pageStart     分頁開始位置
     * @param pageSize      每頁顯示條數
     * @param sortBuilders  排序Builder
     * @param queryBuilder  查詢Builder
     * @param clazz         返回類型
     * @return java.util.List<T>
     */
    public <T> List<T>findPageSearch(String indexNames, Integer pageStart, Integer pageSize, List<SortBuilder> sortBuilders, QueryBuilder queryBuilder, Class<T> clazz) {
        try {
            SearchRequest searchRequest = new SearchRequest(indexNames);
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            if(pageStart != null) {
                sourceBuilder.from(pageStart);
                sourceBuilder.size(pageSize);
            }
            sourceBuilder.query(queryBuilder);
            if(sortBuilders != null) {
                //rank排序
                for (SortBuilder builder : sortBuilders) {
                    sourceBuilder.sort(builder);
                }
            }
            searchRequest.source(sourceBuilder);
            searchRequest.types(TYPE);
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest);
            SearchHits searchHits = searchResponse.getHits();
            List<T> results = new ArrayList<>();
            for(SearchHit hit : searchHits){
                T t = JSON.parseObject(hit.getSourceAsString(),clazz);
                results.add(t);
            }
            return results;
        }catch (Exception e){
            throw new RuntimeException("multiGetByIds exception",e);
        }
    }

    /**
     * 判斷索引是否存在
     *
     * @date 2019/12/10
     * @param esIndex 索引名
     * @return boolean
     */
    public boolean existsIndex(String esIndex) {
        boolean exist = false;
        try {
            Response response = restHighLevelClient.getLowLevelClient().performRequest("HEAD", esIndex);
            exist = response.getStatusLine().getReasonPhrase().equals("OK");
        } catch (IOException e) {
            throw new RuntimeException("existsIndex exception",e);
        }
        return exist;
    }

    /**
     * 創建索引
     *
     * @date 2019/12/11
     * @param index 索引名稱
     * @param settings setting設置,可空
     * @param properties properties設置
     * @return boolean
     */
    public boolean createIndex(String index,Map<String,Object> settings,Map<String,Map<String,String>> properties){
        //創建索引請求對象,並設置索引名稱
        CreateIndexRequest createIndexRequest = new CreateIndexRequest(index);
        //設置索引參數
        Settings.Builder builder = Settings.builder();
        if(!CollectionUtils.isEmpty(settings)){
            for(Map.Entry<String,Object> entry : settings.entrySet()){
                if(entry.getValue() instanceof String){
                    builder.put(entry.getKey(),(String) entry.getValue());
                }else if(entry.getValue() instanceof Integer){
                    builder.put(entry.getKey(),(Integer) entry.getValue());
                }
            }
            createIndexRequest.settings(builder);
        }
        if(!CollectionUtils.isEmpty(properties)) {
            JSONObject sourceJson = new JSONObject();
            sourceJson.put("properties", JSONObject.toJSON(properties));
            //設置映射
            createIndexRequest.mapping(TYPE, sourceJson.toJSONString(), XContentType.JSON);
        }
        //創建索引操作客戶端
        IndicesClient indices = restHighLevelClient.indices();
        try {
            //創建響應對象
            CreateIndexResponse createIndexResponse = indices.create(createIndexRequest);
            return createIndexResponse.isAcknowledged();
        } catch (IOException e) {
            log.error("創建索引異常",e);
            throw new RuntimeException("創建索引異常",e);
        }
    }

    /**
     * 刪除索引
     *
     * @date 2019/12/11
     * @param indexName 索引名稱
     * @return boolean
     */
    public boolean deleteIndex(String indexName) {
        try {
            DeleteIndexRequest request = new DeleteIndexRequest(indexName);
            DeleteIndexResponse deleteIndexResponse = restHighLevelClient.indices().delete(request);
            return deleteIndexResponse.isAcknowledged();
        }catch (Exception e){
            log.error("刪除索引{}異常",indexName,e);
            throw new RuntimeException("刪除索引異常",e);
        }
    }

    /**
     * 刪除索引
     *
     * @date 2019/12/11
     * @param indexNames 索引名稱
     * @return boolean
     */
    public boolean deleteIndex(String ... indexNames) {
        try {
            DeleteIndexRequest request = new DeleteIndexRequest(indexNames);
            DeleteIndexResponse deleteIndexResponse = restHighLevelClient.indices().delete(request);
            return deleteIndexResponse.isAcknowledged();
        }catch (Exception e){
            log.error("刪除索引{}異常",indexNames,e);
            throw new RuntimeException("刪除索引異常",e);
        }
    }

    /**
     * 修改索引的settings
     *
     * @date 2019/12/11
     * @param indexName 索引名稱
     * @param settings 索引settings
     * @return boolean
     */
    public boolean putSetting(String indexName,Map<String,Object> settings){
        UpdateSettingsRequest request = new UpdateSettingsRequest(indexName);
        request.settings(settings);
        try {
            UpdateSettingsResponse updateSettingsResponse = restHighLevelClient.indices().putSettings(request);
            return updateSettingsResponse.isAcknowledged();
        } catch (IOException e) {
            log.error("索引修改setting異常",e);
            throw new RuntimeException("索引修改setting異常",e);
        }
    }

    /**
     * 插入或更新索引數據
     *
     * @date 2019/12/12
     * @param indexName     索引名稱
     * @param id            id的名稱
     * @param data          插入的數據
     * @return String       返回插入或者更新的id
     */
    public <T> String insert(String indexName,String id,T data){
        JSONObject jsonObject = (JSONObject) JSONObject.toJSON(data);
        IndexRequest indexRequest = new IndexRequest(indexName, TYPE, jsonObject.getString(id))
                .source(jsonObject.toJSONString(),XContentType.JSON);
        IndexResponse indexResponse = null;
        try {
            indexResponse = restHighLevelClient.index(indexRequest);
        } catch (IOException e) {
            log.error("es插入異常",e);
            throw  new RuntimeException("es插入異常",e);
        }
        if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {
            return  indexResponse.getId();
        } else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {
            return indexResponse.getId();
        }
        return null;
    }
    
    /**
     * 批量插入索引數據
     * 
     * @date 2019/12/11 
     * @param indexName     索引名稱
     * @param id            索引的id名稱
     * @param  list         插入的數據
     * @return boolean
     */
    public <T>  boolean batchInsert(String indexName,String id,List<T> list){
        BulkRequest request = new BulkRequest();
        //空數據直接返回成功
        if(CollectionUtils.isEmpty(list)){
            return true;
        }
        for(T object : list){
            JSONObject jsonObject = (JSONObject) JSONObject.toJSON(object);
            String json = jsonObject.toString(SerializerFeature.WriteNullNumberAsZero);
            request.add(new IndexRequest(indexName, TYPE, jsonObject.getString(id))
                    .source(json,XContentType.JSON));
        }
        BulkResponse bulkResponse = null;
        try {
            bulkResponse = restHighLevelClient.bulk(request);
        } catch (IOException e) {
            log.error("批量插入es異常",e);
            throw new RuntimeException("批量插入es異常",e);
        }
        //如果返回結果有一項是失敗
        if(bulkResponse != null && bulkResponse.hasFailures()){
            for (BulkItemResponse bulkItemResponse : bulkResponse) {
                //因爲是添加操作,所以只處理添加的響應
                if (bulkItemResponse.getOpType() == DocWriteRequest.OpType.INDEX
                        || bulkItemResponse.getOpType() == DocWriteRequest.OpType.CREATE) {
                    if (bulkItemResponse.isFailed()) {
                        BulkItemResponse.Failure failure = bulkItemResponse.getFailure();
                        log.error("批量插入索引失敗:{}",failure);
                    }
                }
            }
            return false;
        }else if(bulkResponse == null){
            return false;
        }
        return true;
    }
}

五.更多操作參考官方文檔:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/6.3/java-rest-high-document-index.html#java-rest-high-document-index

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章