HighLevelRestClient操作ES幾種常見API總結

一、環境配置

版本在這裏一定要注意,es從6.3之後api發生了很多變化,很多api被棄用了。所以這裏用的是6.8.4.

導入jar包


  <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>6.8.4</version>
        </dependency>

        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>6.8.4</version>
        </dependency>


配置文件yml:

elasticsearch:
  host: ip
  port: port  //這裏是9200端口對應rest請求
//這裏配置了low和high兩種
@Data
@Configuration
@ConfigurationProperties(prefix = "elasticsearch")
public class EsConfig{
    private String host;
    private Integer port;

    @Bean(destroyMethod = "close")
    public RestClient restClient() {
        // 如果有多個從節點可以持續在內部new多個HttpHost,參數1是IP,參數2是端口,參數3是通信協議
        RestClientBuilder clientBuilder = RestClient.builder(new HttpHost(host, port, "http"));
        // 設置Header編碼
        Header[] defaultHeaders = {new BasicHeader("content-type", "application/json")};
        clientBuilder.setDefaultHeaders(defaultHeaders);
        // 添加其他配置,這些配置都是可選的,詳情配置可看https://blog.csdn.net/jacksonary/article/details/82729556
        return clientBuilder.build();
    }


    @Bean(destroyMethod = "close")
    public RestHighLevelClient client() {
        return new RestHighLevelClient(RestClient.builder(
                new HttpHost(host, port, "http")
        ));
    }
    
}

二、常見操作的API

1、添加索引,並創建mapping
這種操作常見於,es在直接向沒有設定mapping的索引中添加數據時,一些數據類型不能動態匹配比如,座標geo-point類型,ip類型等等,需要我們手動先創建好mapping,再進行數據添加操作。需要注意的是,新建索引要用CreateIndexRequest ,如果索引已經存在,則要用PutMappingRequest來進行修改了。
創建mapping時只需要創建特殊指定的字段就可以了。

import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;

import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;


@Service
@Slf4j
public class EsMappingCreateUtil {

	
    @Autowired
    private RestHighLevelClient highLevelClient;

    public  AcknowledgedResponse createStationMapping(String indexName){
        //需要先創建索引
        CreateIndexRequest request = new CreateIndexRequest(indexName);

        String m=  "{\n" +
                "  \"properties\": {" +
                "    \"location\": {" +
                "      \"type\": \"geo_point\"" +
                "    }," +
                "    \"baiduLocation\": {" +
                "      \"type\": \"geo_point\"" +
                "    }" +
                "  }" +
                "}";
        request.mapping(m, XContentType.JSON);

        try {
       		 //查詢索引是否存在,這裏索引名稱既可以是索引也可以是別名
            GetIndexRequest getIndexRequest = new GetIndexRequest(indexName);
            boolean exists = highLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
            if(!exists){
                AcknowledgedResponse getMappingResponse = highLevelClient.indices().create(request, RequestOptions.DEFAULT);
                log.info("創建索引maping成功 {}",indexName);
                return putMappingResponse;

            }
            log.info("索引{}已經存在",indexName);

        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

2、批量添加索引

此操作用於批量將數據添加進es索引庫中。切記數據中不能存在空的數據。否則添加失敗。
  BulkRequest bulkRequest=new BulkRequest();
            log.info("start={},endnow={}",start,endNow);
            stationRepository.selectListByPage(start,endNow).forEach(station->{
                JSONObject jsonObject=JSONObject.parseObject(station.getLocationStr());
                station.setLocation(jsonObject);
                JSONObject baiduLocation=JSONObject.parseObject(station.getBaiduLocationStr());
                station.setBaiduLocation(baiduLocation);
                bulkRequest.add(createIndexRequest(station,stationIndexName,EsConstant.STATION_TYPE,station.getStationId()), XContentType.JSON);
            });


	  try {

                BulkResponse bulkResponse=highLevelClient.bulk(bulkRequest,RequestOptions.DEFAULT);
                log.info("索引{}批量添加結果bulkResponse={}",stationIndexName,JSONObject.toJSONString(bulkResponse));


            } catch (IOException e) {
                e.printStackTrace();
            }

 private IndexRequest createIndexRequest(final Object data, final String indexName, final String type,  final String id) {
        return new IndexRequest(indexName).id(id).type(type).source(beanToMap(data));

    }

3、根據索引別名,查詢所有的索引名稱

此操作,通常會用於重建索引的時候,爲了查詢統一用別名來操作。會將每次新建的索引賦予一個統一的別名,但是之前的索引中的別名需要刪除,所以,需要根據別名先將索引名稱查詢出來進行刪除,添加和刪除操作見下一條。

但是這裏也有需要注意的地方,查詢如果是空的話,返回的結果並不是null,而是bytes或者empty,所以,我們在處理的時候也要注意。

   /**
     * 根據別名查詢所有的索引名稱
     * @param aliasName 別名
     * @return 索引名稱集合
     */
    private Set<String> getIndexName(String aliasName){
        Map<String,Object> resultMap=new HashMap<>();
        try {
            //先判斷別名是否存在
            GetIndexRequest getIndexRequest = new GetIndexRequest(aliasName);
            boolean exists = highLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
            log.info("索引別名{}查詢是否存在{}",aliasName,exists);
            if(exists){
                Request request=new Request("GET","/_alias/"+aliasName);
                Response response=highLevelClient.getLowLevelClient().performRequest(request);

                if(response!=null){
                    resultMap=beanToMap(EntityUtils.toString(response.getEntity()));
                }
                return resultMap.keySet();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;

    }

4、索引別名添加和刪除

 private void modifyAlias(String indexName,String alias,String method){

        Map<String,Object> deleteAlias=new HashMap<>();
        Map<String,String> methodMap=new HashMap<>();
        methodMap.put("index",indexName);
        methodMap.put("alias",alias);
        deleteAlias.put(method,methodMap);
        Object[] actions=new Object[1];
        actions[0]=deleteAlias;
        Map<String,Object> params=new HashMap<>();
        params.put("actions",actions);
        log.info("params={}",JSONObject.toJSONString(params));
        try {

            if("remove".equals(actions)){
                GetIndexRequest getIndexRequest = new GetIndexRequest(alias);
                boolean exists = highLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
                log.info("刪除索引別名前查詢索引別名{}是否存在{}",alias,exists);
                if(!exists){
                    return;
                }
            }
            Request request=new Request("POST","/_aliases");
            HttpEntity entity = new NStringEntity(JSONObject.toJSONString(params), ContentType.APPLICATION_JSON);
            request.setEntity(entity);
            Response response=highLevelClient.getLowLevelClient().performRequest(request);
            log.info(JSONObject.toJSONString(response));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
//這裏是調用添加和刪除方法
 private void addAliasName(String indexName,String aliasName){
        Set<String> indexSet=getIndexName(aliasName);
        if(indexSet!=null){
            indexSet.forEach(index->{
            //特殊處理一下查詢出來的結果
                if(index!=null && !"bytes".equals(index) && !"empty".equals(index)){
                    modifyAlias(index,aliasName,"remove");
                }
            });
        }
        modifyAlias(indexName,aliasName,"add");
    }

5、查詢

對於索引操作來說,查詢是最常見的操作了。所以這裏只舉個最常見的例子。
  SearchRequest searchRequest=new SearchRequest(EsConstant.STATION_INDEX_NAME_ALIAS);
        searchRequest.types(EsConstant.STATION_TYPE);
        String searchKeyword="*"+keyword+"*";
        searchRequest.source(buildKeywordSearchBuilder(searchKeyword));

        try {
            SearchResponse searchResponse=highLevelClient.search(searchRequest,RequestOptions.DEFAULT);
            SearchHits searchHits=searchResponse.getHits();
            List<Object> stationList=new ArrayList<>(20);
            if(searchHits!=null && searchHits.getHits()!=null){

                for(SearchHit hit:searchHits.getHits()){
                    OperatorStation station= JSONObject.parseObject(hit.getSourceAsString(),OperatorStation.class);
                    Map<String,Object> map=new HashMap<>(20);
                 	map.put("id",station.getId());
                    stationList.add(map);
                }
            }

//構造查詢條件
SearchSourceBuilder buildKeywordSearchBuilder(String searchKeyword){
        BoolQueryBuilder boolQueryBuilder=new BoolQueryBuilder();
        boolQueryBuilder.must(QueryBuilders.matchQuery("字段",條件))
                .must(QueryBuilders.matchQuery("stationOnLine",條件))
                .should(QueryBuilders.wildcardQuery("字段",searchKeyword))
                .should(QueryBuilders.wildcardQuery("字段",searchKeyword));


        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(boolQueryBuilder);
        sourceBuilder.from(0);
        sourceBuilder.size(15); //分頁
        log.info("station-find-keyword query string ={}",sourceBuilder.toString());
        return sourceBuilder;
    }


以上是我總結的一些基本操作。

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