基于elasticsearch官方提供的组件实现增删查等操作

目前主要的使用连接elasticsearch的组件有:transportjest官方的java high level rest client三种,这三种的对比如下图:

 

Java high level rest client

jest

transport

版本

官方的,每个es版本均有其客户端

截止当前2019年,最新版本6.3.2,支持es版本6.3.1,对es高版本是否支持,不确定,可能会有坑

Es7.0计划删除该功能,es8.0完全删除,故该方式忽略

增删改查

支持

支持

支持

bulk

支持

支持

支持

复杂查询

支持范围查询,聚合查询

支持范围查询,聚合查询

支持

查询删除

6.4及之前版本不支持,但自身有对rest client封装,可直接与es服务http方式连接实现查询删除(delete_by_query))

支持

支持

 

 

 

 

由于java high level rest client这种方式,网上的资料特别少,我在使用的时候,查阅了很多资料,经实践之后,把如何使用该组件实现增删查(修改类似,此文忽略),跟大家分享下。

使用的组件如下:

Java:1.8

ES版本:6.5.4

java high level rest client版本:6.5.4

Spring boot版本:1.5

直接分享代码,如下

第一步,连接

Pom.xml配置如下:


    org.elasticsearch.client
    elasticsearch-rest-high-level-client
    6.5.4

application.yml配置如下:

esclient:
  host: 10.37.147.56
  port: 9200
  schema: http
  connectTimeOut: 1000
  socketTimeOut: 30000
  connectionRequestTimeOut: 500
  maxConnectNum: 100
  maxCconnectPerRoute: 10

EsClientSetting.java

@ConfigurationProperties(prefix = "esclient")
public class EsClientSetting {

    private String host;

    private int  port;

    private String schema;

    private int connectTimeOut;

    private int socketTimeOut;

    private int connectionRequestTimeOut;

    private int maxConnectNum;

    private int maxCconnectPerRoute;

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public String getSchema() {
        return schema;
    }

    public void setSchema(String schema) {
        this.schema = schema;
    }

    public int getConnectTimeOut() {
        return connectTimeOut;
    }

    public void setConnectTimeOut(int connectTimeOut) {
        this.connectTimeOut = connectTimeOut;
    }

    public int getSocketTimeOut() {
        return socketTimeOut;
    }

    public void setSocketTimeOut(int socketTimeOut) {
        this.socketTimeOut = socketTimeOut;
    }

    public int getConnectionRequestTimeOut() {
        return connectionRequestTimeOut;
    }

    public void setConnectionRequestTimeOut(int connectionRequestTimeOut) {
        this.connectionRequestTimeOut = connectionRequestTimeOut;
    }

    public int getMaxConnectNum() {
        return maxConnectNum;
    }

    public void setMaxConnectNum(int maxConnectNum) {
        this.maxConnectNum = maxConnectNum;
    }

    public int getMaxCconnectPerRoute() {
        return maxCconnectPerRoute;
    }

    public void setMaxCconnectPerRoute(int maxCconnectPerRoute) {
        this.maxCconnectPerRoute = maxCconnectPerRoute;
    }

}

配置连接的factory,ESClientFactory.java

public class ESClientFactory {
    public static int CONNECT_TIMEOUT_MILLIS = 1000;
    public static int SOCKET_TIMEOUT_MILLIS = 30000;
    public static int CONNECTION_REQUEST_TIMEOUT_MILLIS = 500;
    public static int MAX_CONN_PER_ROUTE = 10;
    public static int MAX_CONN_TOTAL = 100;

    private static HttpHost HTTP_HOST;
    private RestClientBuilder builder;
    private RestClient restClient;
    private RestHighLevelClient restHighLevelClient;

    private static ESClientFactory eSClientFactory = new ESClientFactory();

    private ESClientFactory(){}

    public static ESClientFactory build(HttpHost httpHost,
                                              Integer maxConnectNum, Integer maxConnectPerRoute){
        HTTP_HOST = httpHost;
        MAX_CONN_TOTAL = maxConnectNum;
        MAX_CONN_PER_ROUTE = maxConnectPerRoute;
        return  eSClientFactory;
    }

    public static ESClientFactory build(HttpHost httpHost,Integer connectTimeOut, Integer socketTimeOut,
                                              Integer connectionRequestTime,Integer maxConnectNum, Integer maxConnectPerRoute){
        HTTP_HOST = httpHost;
        CONNECT_TIMEOUT_MILLIS = connectTimeOut;
        SOCKET_TIMEOUT_MILLIS = socketTimeOut;
        CONNECTION_REQUEST_TIMEOUT_MILLIS = connectionRequestTime;
        MAX_CONN_TOTAL = maxConnectNum;
        MAX_CONN_PER_ROUTE = maxConnectPerRoute;
        return  eSClientFactory;
    }


    public void init(){
        builder = RestClient.builder(HTTP_HOST);
        setConnectTimeOutConfig();
        setMutiConnectConfig();
        restClient = builder.build();
        restHighLevelClient = new RestHighLevelClient(builder);
    }
    // 配置连接时间延时
    public void setConnectTimeOutConfig(){
        builder.setRequestConfigCallback(new RequestConfigCallback() {

            @Override
            public Builder customizeRequestConfig(Builder requestConfigBuilder) {
                requestConfigBuilder.setConnectTimeout(CONNECT_TIMEOUT_MILLIS);
                requestConfigBuilder.setSocketTimeout(SOCKET_TIMEOUT_MILLIS);
                requestConfigBuilder.setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT_MILLIS);
                return requestConfigBuilder;
            }
        });
    }
    // 使用异步httpclient时设置并发连接数
    public void setMutiConnectConfig(){
        builder.setHttpClientConfigCallback(new HttpClientConfigCallback() {

            @Override
            public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
                httpClientBuilder.setMaxConnTotal(MAX_CONN_TOTAL);
                httpClientBuilder.setMaxConnPerRoute(MAX_CONN_PER_ROUTE);
                return httpClientBuilder;
            }
        });
    }

    public RestClient getClient(){
        return restClient;
    }

    public RestHighLevelClient getRhlClient(){
        return restHighLevelClient;
    }

    public void close() {
        if (restClient != null) {
            try {
                restClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        System.out.println("close client");
    }


}

 

配置连接的bean,ESConfig.java

@Configuration
@EnableConfigurationProperties(EsClientSetting.class)
@ComponentScan(basePackageClasses=ESClientFactory.class)
public class ESConfig {

    private static final Logger logger = LoggerFactory.getLogger(ESConfig.class);

    private final EsClientSetting esClientSetting;

    public ESConfig(EsClientSetting esClientSetting){
        this.esClientSetting = esClientSetting;
    }

    @Bean
    public HttpHost httpHost(){
        return new HttpHost(esClientSetting.getHost(),esClientSetting.getPort(),esClientSetting.getSchema());
    }

    @Bean(initMethod="init",destroyMethod="close")
    public ESClientFactory getFactory(){
        return ESClientFactory.
                build(httpHost(), esClientSetting.getConnectTimeOut(), esClientSetting.getSocketTimeOut(),
                        esClientSetting.getConnectionRequestTimeOut(), esClientSetting.getMaxConnectNum(),
                        esClientSetting.getMaxCconnectPerRoute());
    }

    @Bean
    @Scope("singleton")
    public RestClient getRestClient(){
        return getFactory().getClient();
    }

    @Bean
    @Scope("singleton")
    public RestHighLevelClient getRHLClient(){
        return getFactory().getRhlClient();
    }
}

至此,配置es的连接bean就ok了。

第二步,就是使用了,如下

EsClientServiceImpl.java

@Service
public class EsClientServiceImpl implements EsClientService {

    private Logger log = LoggerFactory.getLogger(EsClientServiceImpl.class);

    private Gson gson = new Gson();

    private final RestHighLevelClient rhlClient;

    private RestClient restClient;

    public final static String ESTYPE = "_doc";

    @Autowired
    public EsClientServiceImpl(RestHighLevelClient rhlClient, RestClient restClient) {
        this.rhlClient = rhlClient;
        this.restClient = restClient;
    }

    /**
     * 测试接口
     */
    public void queryByParama(Map params){
//        createIndex();
        addTest();
//        batchAddTest();
//        queryTest();
//        delete();
        deleteByQuery();
    }

    //创建索引--测试
    public void createIndex(){
        CreateIndexRequest request = new CreateIndexRequest("demo2");
        request.settings(Settings.builder()
                .put("index.number_of_shards", 2)
                .put("index.number_of_replicas", 0)
        );
        request.mapping("_doc",
                "{\n" +
                        "  \"_doc\": {\n" +
                        "    \"properties\": {\n" +
                        "      \"title\": {\n" +
                        "        \"type\": \"text\"\n" +
                        "      },\n" +
                        "      \"tag\": {\n" +
                        "        \"type\": \"keyword\"\n" +
                        "      },\n" +
                        "      \"publishTime\": {\n" +
                        "        \"type\": \"date\"\n" +
                        "      }\n" +
                        "    }\n" +
                        "  }\n" +
                        "}",
                XContentType.JSON);
        try {
            rhlClient.indices().create(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //新增--测试
    public void addTest() {
        IndexRequest indexRequest = new IndexRequest("demo2", "_doc");
        News news = new News();
        news.setTitle("2中国产小型无人机的“对手”来了,俄微型拦截导弹便宜量又多");
        news.setTag("军事");
        news.setPublishTime("2018-01-24T23:59:30Z");
        String source = gson.toJson(news).toString();
        indexRequest.source(source, XContentType.JSON);
        try {
            rhlClient.index(indexRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    //批量新增--测试
    public void batchAddTest() {
        BulkRequest bulkRequest = new BulkRequest();
        List requests = generateRequests();
        for (IndexRequest indexRequest : requests) {
            bulkRequest.add(indexRequest);
        }
        try {
            rhlClient.bulk(bulkRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public List generateRequests(){
        List requests = new ArrayList<>();
        requests.add(generateNewsRequest("中印边防军于拉达克举行会晤 强调维护边境和平", "军事", "2018-01-27T08:34:00Z"));
        requests.add(generateNewsRequest("费德勒收郑泫退赛礼 进决赛战西里奇", "体育", "2018-01-26T14:34:00Z"));
        requests.add(generateNewsRequest("欧文否认拿动手术威胁骑士 兴奋全明星联手詹皇", "体育", "2018-01-26T08:34:00Z"));
        requests.add(generateNewsRequest("皇马官方通告拉莫斯伊斯科伤情 将缺阵西甲关键战", "体育", "2018-01-26T20:34:00Z"));
        return requests;
    }

    public IndexRequest generateNewsRequest(String title, String tag, String publishTime){
        IndexRequest indexRequest = new IndexRequest("demo", "demo");
        News news = new News();
        news.setTitle(title);
        news.setTag(tag);
        news.setPublishTime(publishTime);
        String source = gson.toJson(news).toString();
        indexRequest.source(source, XContentType.JSON);
        return indexRequest;
    }

    //按条件查询--测试
    public void queryTest(){
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.from(0);
        sourceBuilder.size(10);
        sourceBuilder.fetchSource(new String[]{"title"}, new String[]{});
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "中国");
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("tag", "军事");
        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("publishTime");
        rangeQueryBuilder.gte("2018-01-23T08:00:00Z");
        rangeQueryBuilder.lte("2018-01-26T20:00:00Z");
        BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
        boolBuilder.must(matchQueryBuilder);
        boolBuilder.must(termQueryBuilder);
        boolBuilder.must(rangeQueryBuilder);
        sourceBuilder.query(boolBuilder);
        SearchRequest searchRequest = new SearchRequest("demo2");
        searchRequest.types("_doc");
        searchRequest.source(sourceBuilder);
        try {
            SearchResponse response = rhlClient.search(searchRequest, RequestOptions.DEFAULT);
            System.out.println(response);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    //查询删除--使用restClient
    public void delete() {
        String index = "demo2";
        String type = "_doc";
        String endPoint = "/" + index + "/" + type +"/_delete_by_query";
        String source = genereateQueryString();
        HttpEntity entity = new NStringEntity(source, ContentType.APPLICATION_JSON);
        try {
            Request request = new Request("POST", endPoint);
            request.setEntity(entity);
            restClient.performRequest(request);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    public String genereateQueryString(){
        IndexRequest indexRequest = new IndexRequest();
        XContentBuilder builder;
        try {
            builder = JsonXContent.contentBuilder()
                    .startObject()
                        .startObject("query")
                            .startObject("bool")
                                .startArray("filter")
                                        .startObject()
                                            .startObject("term")
                                                .field("tag","军事")
                                            .endObject()
                                        .endObject()
                                        .startObject()
                                            .startObject("range")
                                                .startObject("publishTime")
                                                    .field("gte","2018-01-23T08:00:00Z")
                                                    .field("lte","2018-01-26T20:00:00Z")
                                                .endObject()
                                            .endObject()
                                        .endObject()
                                .endArray()
                            .endObject()
                        .endObject()
                    .endObject();
            indexRequest.source(builder);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        String source = indexRequest.source().utf8ToString();
        return source;
    }

    //查询删除--deleteByQuery方法api,es6.5之后的版本直接支持,但是其实质还是使用的restClient去执行deleteByQuery方法
    public void deleteByQuery(){
        DeleteByQueryRequest request = new DeleteByQueryRequest("demo2");
        request.types("_doc");
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "中国");
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("tag", "军事");
        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("publishTime");
        rangeQueryBuilder.gte("2018-01-23T08:00:00Z");
        rangeQueryBuilder.lte("2018-01-26T20:00:00Z");
        BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
        boolBuilder.must(matchQueryBuilder);
        boolBuilder.must(termQueryBuilder);
        boolBuilder.must(rangeQueryBuilder);
        request.setQuery(boolBuilder);
        request.setConflicts("proceed");
        try {
            BulkByScrollResponse bulkResponse = rhlClient.deleteByQuery(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

以上就是如何使用java high level rest client高版本实现对es的相关操作,只是个中案例,不全面,还请多多理解,如有不对指出,欢迎指正!

你可能感兴趣的:(elasticsearch)