• esrestHighLevel java api实战


    版本为7.9.1,大体分为pom引入,封装注入Bean:RestHighLevelClient;封装具体的操作类,service层调用

    pom引入

            <elasticsearch.version>7.9.1</elasticsearch.version>
            <dependency>
                <groupId>org.elasticsearch</groupId>
                <artifactId>elasticsearch</artifactId>
                <version>${elasticsearch.version}</version>
            </dependency>
            <dependency>
                <groupId>org.elasticsearch.client</groupId>
                <artifactId>elasticsearch-rest-high-level-client</artifactId>
                <exclusions>
                    <exclusion>
                        <groupId>org.elasticsearch</groupId>
                        <artifactId>elasticsearch</artifactId>
                    </exclusion>
                </exclusions>
                <version>${elasticsearch.version}</version>
            </dependency>

    注入RestHighLevelClient 

    @Component
    public class RestHighLevelClient {
        @Value("${elasticsearch.http.list}")
        private String httpList;
        @Value("${elasticsearch.max.retry.timeout}")
        private Integer maxRetryTimeoutMillis;
        @Value("${elasticsearch.connect.timeout}")
        private Integer connectTimeout;
        @Value("${elasticsearch.socket.timeout}")
        private Integer socketTimeout;
        @Value("${elasticsearch.connection.request.timeout}")
        private Integer connectionRequestTimeout;
    
        @Bean
        public RestHighLevelClient restHighLevelClient() throws Exception {
            List<HttpHost> httpHosts = new ArrayList<>();
            if (StringUtils.isNotBlank(httpList)){
                Arrays.stream(httpList.split(",")).forEach(ipAndPort -> httpHosts.add(HttpHost.create(HttpConstants.HTTP_PROTOCOL + ipAndPort)));
            }
           
            final RestClientBuilder esRestClientBuilder = RestClient.builder(httpHosts.toArray(new HttpHost[httpHosts.size()]))
    //                .setMaxRetryTimeoutMillis(maxRetryTimeoutMillis)
                    .setHttpClientConfigCallback(httpClientBuilder -> {
                        RequestConfig.Builder requestConfigBuilder = RequestConfig.custom()
                                //超时时间60s
                                .setConnectTimeout(connectTimeout)
                                //Socket超时时间设置
                                .setSocketTimeout(socketTimeout)
                                .setConnectionRequestTimeout(connectionRequestTimeout);
                        httpClientBuilder.setDefaultRequestConfig(requestConfigBuilder.build());
                        return httpClientBuilder;
                    });
            return new RestHighLevelClient(esRestClientBuilder);
        }
    
    }

    封装es的具体操作接口

    首先注入RestHighLevelClient

    @Autowired
    private RestHighLevelClientDelegate restClient;

    操作接口有很多,大体可以分为定义操作:index,alias,mapping,数据写入操作:document,template,检索操作:query检索和agg聚合查询

    • 查询es集群状态
        public ClusterHealthStatus healthCheck() throws IOException {
            ClusterHealthRequest request = new ClusterHealthRequest();
            request.timeout(TimeValue.timeValueSeconds(30));
            ClusterHealthResponse response = restClient.cluster().health(request, RequestOptions.DEFAULT);
            return response.getStatus();
        }
    • 查询索引是否存在
       /**
         * index API
         * 判断索引是否存在
         *
         * @param index
         * @return
         * @throws IOException
         */
        public Boolean indexExists(String index) throws IOException {
            GetIndexRequest request = new GetIndexRequest(index);
            return restClient.indices().exists(request, RequestOptions.DEFAULT);
        }
    • 创建索引
       /**
         * index API
         * 创建索引
         * 尽量使用Map构造后提供json格式的参数
         */
        public String createIndex(String index, String settings, String mappings, List<Alias> aliases) throws IOException {
            CreateIndexRequest request = new CreateIndexRequest(index);
            if (StringUtils.isNotEmpty(settings)) {
                request.settings(settings, XContentType.JSON);
            }
            if (StringUtils.isNotEmpty(mappings)) {
                request.mapping(mappings, XContentType.JSON);
            }
            if (CollUtil.isNotEmpty(aliases)) {
                request.aliases(aliases);
            }
            CreateIndexResponse response = restClient.indices().create(request, RequestOptions.DEFAULT);
            return response.index();
        }
    • 删除索引
       /**
         * index API
         * 删除索引
         *
         * @param index 索引名
         */
        public boolean deleteIndex(String index) throws Exception {
            DeleteIndexRequest request = new DeleteIndexRequest(index);
            AcknowledgedResponse response = restClient.indices().delete(request, RequestOptions.DEFAULT);
            return response.isAcknowledged();
        }
    • 查询给定索引的mappings
       /**
         * 获取mappings
         *
         * @param index 索引名
         */
        public Map<String, Object> getMappings(@NotNull String index) throws Exception {
            GetMappingsRequest request = new GetMappingsRequest().indices(index);
            GetMappingsResponse response = restClient.indices().getMapping(request, RequestOptions.DEFAULT);
            Map<String, MappingMetadata> allMappings = response.mappings();
            MappingMetadata indexMapping = allMappings.get(index);
            if (Objects.nonNull(indexMapping)) {
                Object obj = indexMapping.getSourceAsMap().get("properties");
                return (Map<String, Object>) obj;
            }
            return null;
        }
    • 开启和关闭索引
       /**
         * index API
         * 关闭索引后,该索引无法再执行读写
         *
         * @param index 索引名
         */
        public boolean closeIndex(String index) throws Exception {
            CloseIndexRequest request = new CloseIndexRequest("index");
            AcknowledgedResponse response = restClient.indices().close(request, RequestOptions.DEFAULT);
            return response.isAcknowledged();
        }
    
        /**
         * index API
         * 开启索引,与关闭相反
         *
         * @param index 索引名
         */
        public boolean openIndex(String index) throws Exception {
            OpenIndexRequest request = new OpenIndexRequest(index);
            AcknowledgedResponse response = restClient.indices().open(request, RequestOptions.DEFAULT);
            return response.isAcknowledged();
        }
    • 创建和删除存储策略
       /**
         * 判断存储策略是否存在
         *
         * @param policyName 存储策略名称
         * @return {@code true}表示存在,{@code false}表示不存在
         * @throws Exception 当解析返回结果失败,或者请求超时或者无响应等时,会抛出异常。
         */
        public boolean policyExists(String policyName) throws Exception {
            GetLifecyclePolicyRequest request =
                    new GetLifecyclePolicyRequest(policyName);
            GetLifecyclePolicyResponse response = restClient.indexLifecycle()
                    .getLifecyclePolicy(request, RequestOptions.DEFAULT);
            ImmutableOpenMap<String, LifecyclePolicyMetadata> policies = response.getPolicies();
            LifecyclePolicyMetadata myPolicyMetadata = policies.get(policyName);
            return Objects.nonNull(myPolicyMetadata);
        }
       /**
         * 创建存储策略
         *
         * @param policyName 存储策略名称
         * @param days       保存的天数
         * @return {@code true}表示执行成功,{@code false}表示执行失败
         * @throws Exception 当解析返回结果失败,或者请求超时或者无响应等时,会抛出异常。
         */
        public boolean createPolicy(String policyName, Integer days) throws IOException {
            Map<String, Phase> phases = new HashMap<>();
            Map<String, LifecycleAction> hotActions = new HashMap<>();
            hotActions.put(RolloverAction.NAME, new RolloverAction(
                    new ByteSizeValue(30, ByteSizeUnit.GB), new TimeValue(1, TimeUnit.DAYS), null));
            phases.put("hot", new Phase("hot", TimeValue.ZERO, hotActions));
    
            Map<String, LifecycleAction> deleteActions =
                    Collections.singletonMap(DeleteAction.NAME, new DeleteAction());
            phases.put("delete", new Phase("delete", new TimeValue(days, TimeUnit.DAYS), deleteActions));
    
            LifecyclePolicy policy = new LifecyclePolicy(policyName, phases);
            PutLifecyclePolicyRequest request = new PutLifecyclePolicyRequest(policy);
            org.elasticsearch.client.core.AcknowledgedResponse response = restClient.indexLifecycle()
                    .putLifecyclePolicy(request, RequestOptions.DEFAULT);
            return response.isAcknowledged();
        }
    
        /**
         * 删除存储策略
         *
         * @param policyName 存储策略名称
         * @return {@code true}表示执行成功,{@code false}表示执行失败
         * @throws Exception 当解析返回结果失败,或者请求超时或者无响应等时,会抛出异常。
         */
        public boolean deletePolicy(String policyName) throws Exception {
            DeleteLifecyclePolicyRequest request =
                    new DeleteLifecyclePolicyRequest(policyName);
            org.elasticsearch.client.core.AcknowledgedResponse response = restClient.indexLifecycle()
                    .deleteLifecyclePolicy(request, RequestOptions.DEFAULT);
            return response.isAcknowledged();
        }
    • 创建和删除索引模板
       /**
         * 创建索引模板
         *
         * @param templateName 模板名
         * @param patterns     索引名的通配符 如 log_*
         * @param alias        可选,索引别名
         * @param mappings     映射
         * @param setting      设置
         * @return 是否创建成功
         * @throws Exception 当解析返回结果失败,或者请求超时或者无响应等时,会抛出异常。
         */
        public boolean createTemplate(@NotNull String templateName,
                                      List<String> patterns,
                                      String alias,
                                      String mappings,
                                      Settings.Builder setting) throws IOException {
            PutIndexTemplateRequest request = new PutIndexTemplateRequest(templateName);
            request.patterns(patterns);
            if (setting != null) {
                request.settings(setting);
            }
            if (mappings != null) {
                request.mapping(mappings, XContentType.JSON);
            }
            //可以设置filter和searchRouting
            if (alias != null) {
                request.alias(new Alias(alias));
            }
            //设置已经存在的模板不被覆盖
            request.create(true);
            AcknowledgedResponse response = restClient.indices().putTemplate(request, RequestOptions.DEFAULT);
            return response.isAcknowledged();
        }
    
        /**
         * 删除索引模板
         *
         * @param templateName 索引模板的名称
         * @return {@code true}表示执行成功,{@code false}表示执行失败
         * @throws Exception 当解析返回结果失败,或者请求超时或者无响应等时,会抛出异常。
         */
        public boolean deleteTemplate(String templateName) throws Exception {
            DeleteIndexTemplateRequest request = new DeleteIndexTemplateRequest(templateName);
            AcknowledgedResponse deleteTemplateAcknowledge = restClient.indices().deleteTemplate(request, RequestOptions.DEFAULT);
            return deleteTemplateAcknowledge.isAcknowledged();
        }
    
        /**
         * 判断索引模板是否存在
         *
         * @param templateName 索引模板的名称
         * @return {@code true}表示存在,{@code false}表示不存在
         * @throws Exception 当解析返回结果失败,或者请求超时或者无响应等时,会抛出异常。
         */
        public boolean templateExists(String templateName) throws Exception {
            IndexTemplatesExistRequest request = new IndexTemplatesExistRequest(templateName);
            return restClient.indices().existsTemplate(request, RequestOptions.DEFAULT);
        }

    -------------------------------------------------------------------------------------------

    • 一般的分页查询和结果解析
       /**
         * 分页查询
         *
         * @param index        索引名
         * @param queryBuilder 查询条件
         * @param pageNum      第几页
         * @param pageSize     每页条数
         * @return 返回SearchHits, 由调用方处理
         * @throws IOException 查询异常,抛出到真正的调用业务的逻辑去处理
         */
        public SearchResponse searchByPage(String[] index, QueryBuilder queryBuilder, String sort, Integer pageNum, Integer pageSize) throws Exception {
            SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.searchSource()
                    .query(queryBuilder)
                    .size(pageSize)
                    .from((pageNum - 1) * pageSize);
            if (sort != null) {
                searchSourceBuilder.sort(SortBuilders.fieldSort(Constants.DEFAULT_FIELD_NAME).order(SortOrder.fromString(sort)).unmappedType("keyword"));
            }
            SearchRequest searchRequest = Requests.searchRequest(index)
                    .source(searchSourceBuilder)
                    .searchType(SearchType.QUERY_THEN_FETCH);
            log.info("query DSL:[{}]", searchSourceBuilder);
            return restClient.search(searchRequest, RequestOptions.DEFAULT);
        }
        
        SearchResponse response = esService.searchByPage(new String[]{index}, queryBuilder, sort, pageNum, pageSize);
        SearchHit[] hitArr = response.getHits().getHits();
        List<SearchHit> hitList = Arrays.asList(hitArr);
        List<Map<String, Object>> res = new ArrayList<>();
        if (CollUtil.isNotEmpty(hitList)) {
           for (SearchHit hit : hitList) {
               res.add(new HashMap<String, Object>() {{
                   Map<String, Object> sourceAsMap = hit.getSourceAsMap();                      
                   put("_source", sourceAsMap);
                   put("_index", hit.getIndex());                      
                   put("_id", hit.getId());
                   }});
           }
        } 
    • 一般的count聚合
    /**
         * count查询
         *
         * @param index
         * @param qb
         * @return
         * @throws IOException
         */
        public long count(String index, QueryBuilder qb) throws Exception {
            CountRequest countRequest = new CountRequest();
            countRequest.indices(index).query(qb);
            CountResponse response = restClient.count(countRequest, RequestOptions.DEFAULT);
            return response.getCount();
        }
    
       /**
         * 聚合查询count
         * 可考虑按普通查询,然后取出searchHits.total属性
         *
         * @param index     索引名(别名)
         * @param fieldName 使用主键
         * @param qb        条件
         * @return 条数
         * @throws IOException 抛出异常,让调用方处理
         */
        public long count(String index, String fieldName, QueryBuilder qb) throws Exception {
            AggregationBuilder countBuilder = AggregationBuilders.count("countResult").field("log_id");
            SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.searchSource()
                    .query(qb)
                    .size(0)
                    .aggregation(countBuilder);
            SearchRequest searchRequest = Requests.searchRequest(index).source(searchSourceBuilder).searchType(SearchType.QUERY_THEN_FETCH);
            SearchResponse response = restClient.search(searchRequest, RequestOptions.DEFAULT);
            ValueCount count = response.getAggregations().get("countResult");
            return count.getValue();
        }
    • 一般的sum聚合
       /**
         * 聚合查询-sum
         * size设置为0表示不返回参与聚合的记录
         *
         * @param index     索引名(别名)
         * @param fieldName 聚合的字段
         * @param qb        聚合的条件
         * @return 聚合的结果 double类型
         * @throws IOException 聚合异常抛出到调用方处理
         */
        public double sum(String index, String fieldName, QueryBuilder qb) throws Exception {
            AggregationBuilder sumBuilder = AggregationBuilders.sum("sumResult").field(fieldName);
            SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.searchSource()
                    .query(qb)
                    .size(0)
                    .aggregation(sumBuilder);
            log.info("query DSL:[{}]", searchSourceBuilder);
            SearchRequest searchRequest = Requests.searchRequest(index).source(searchSourceBuilder).searchType(SearchType.QUERY_THEN_FETCH);
            SearchResponse response = restClient.search(searchRequest, RequestOptions.DEFAULT);
            Sum sum = response.getAggregations().get("sumResult");
            return sum.getValue();
        }
    • 一般的count+group by聚合
       /**
         * 聚合查询  terms
         * size设置为0表示不返回参与聚合的记录
         *
         * @param index    索引名(别名)
         * @param termName 聚合的字段
         * @param qb       聚合的条件
         * @return 聚合的结果 double类型
         * @throws IOException 聚合异常抛出到调用方处理
         */
        public Terms terms(String index, String termName, QueryBuilder qb) throws Exception {
            TermsAggregationBuilder term = AggregationBuilders.terms("termResult").field(termName).size(100);
            SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.searchSource()
                    .query(qb)
                    .size(0)
                    .aggregation(term);
            log.info("query DSL:[{}]", searchSourceBuilder);
            SearchRequest searchRequest = Requests.searchRequest(index).source(searchSourceBuilder).searchType(SearchType.QUERY_THEN_FETCH);
            SearchResponse response = restClient.search(searchRequest, RequestOptions.DEFAULT);
            return response.getAggregations().get("termResult");
        }
    • 按天count+group by 聚合
       /**
         * 聚合查询  termsByDay
         * size设置为0表示不返回参与聚合的记录
         *
         * @param index    索引名(别名)
         * @param termName 聚合的字段
         * @param qb       聚合的条件
         * @return 聚合的结果 double类型
         * @throws IOException 聚合异常抛出到调用方处理
         */
        public Aggregation aggByDay(String index, String termName, QueryBuilder qb) throws Exception {
            // DateHistogramInterval.DAY 加上时区否则聚类不准
            AggregationBuilder term = AggregationBuilders.dateHistogram("histogramResult")
                    .calendarInterval(DateHistogramInterval.DAY)
                    .field(termName)
                    .timeZone(ZoneId.systemDefault());
            SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.searchSource()
                    .query(qb)
                    .size(0)
                    .aggregation(term);
            log.info("query DSL:[{}]", searchSourceBuilder);
            SearchRequest searchRequest = Requests.searchRequest(index).source(searchSourceBuilder).searchType(SearchType.QUERY_THEN_FETCH);
            SearchResponse response = restClient.search(searchRequest, RequestOptions.DEFAULT);
            return response.getAggregations().get("histogramResult");
        }
    • 在指定的时间范围内按照时间进行柱状图统计
       /**
         * 按某个指定的时间字段搜索一定时间范围内,各个细分时间段的记录的数量
         *
         * @param index     搜索的索引,可以同时搜索多个索引
         * @param interval  时间间隔按情况给
         * @param qb        查询条件
         * @param beginTime 搜索范围的开始时间
         * @param endTime   搜索范围的结束时间
         * @return 结果集
         * @throws IOException IO异常
         */
        public List<BucketDto> dateHistogram(String[] index, String interval, QueryBuilder qb, String beginTime, String endTime) throws Exception {
            DateHistogramAggregationBuilder dateHistogramAB = AggregationBuilders
                    .dateHistogram("histogramResult")
                    .field(Constants.DEFAULT_LOG_TIME_FIELD_NAME)
                    .timeZone(ZoneId.systemDefault())
                    .keyed(true)
                    .fixedInterval(new DateHistogramInterval(interval))
                    .format(getDateFormat())//KeyAsString()的格式
                    .minDocCount(0L);//设置返回空桶
            long beginBound = 0;
            long endBound = System.currentTimeMillis();
            try {
                if (StringUtils.isNotBlank(beginTime)) {
                    beginBound = TimeUtils.getLongTime(beginTime);
                }
                if (StringUtils.isNotBlank(endTime)) {
                    endBound = TimeUtils.getLongTime(endTime);
                }
            } catch (Exception e) {
                log.error("search dateHistogram error", e);
                throw new CommonException("时间解析错误");
            }
            dateHistogramAB.extendedBounds(new ExtendedBounds(beginBound, endBound));//如果设置返回空桶,必须设置时间边界,否则无效
            SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.searchSource()
                    .query(qb)
                    .size(0)
                    .aggregation(dateHistogramAB);
            log.info("query DSL:[{}]", searchSourceBuilder);
            SearchRequest searchRequest = Requests.searchRequest(index).source(searchSourceBuilder).searchType(SearchType.QUERY_THEN_FETCH);
            SearchResponse response = restClient.search(searchRequest, RequestOptions.DEFAULT);
            ParsedDateHistogram histogramResult = response.getAggregations().get("histogramResult");
            List<BucketDto> list = new ArrayList<>();
            for (Histogram.Bucket bucket : histogramResult.getBuckets()) {
                list.add(new BucketDto(bucket.getKeyAsString(), bucket.getDocCount()));
            }
            return list;
        }
    •  一次执行多个count聚合
       /**
         * 一次执行多个count
         */
        public List<Long> multiCount(String index, List<QueryBuilder> qbList) throws Exception {
            MultiSearchRequest request = new MultiSearchRequest();
            AggregationBuilder countBuilder = AggregationBuilders.count("countResult").field("log_id");
            for (QueryBuilder qb : qbList) {
                SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.searchSource()
                        .query(qb)
                        .size(0)
                        .aggregation(countBuilder);
                log.info("query DSL:[{}]", searchSourceBuilder);
                SearchRequest searchRequest = Requests.searchRequest(index).source(searchSourceBuilder).searchType(SearchType.QUERY_THEN_FETCH);
                request.add(searchRequest);
            }
            MultiSearchResponse response = restClient.msearch(request, RequestOptions.DEFAULT);
            List<Long> countList = new ArrayList<>();
            for (MultiSearchResponse.Item item : response.getResponses()) {
                long count = -1L;
                if (!item.isFailure()) {
                    ValueCount valueCount = item.getResponse().getAggregations().get("countResult");
                    count = valueCount.getValue();
                }
                countList.add(count);
            }
            return countList;
        }
    • 一次查询多个
    /**
         * 一次执行多个查询
         *
         * @param index   相同的索引名(别名)
         * @param SSBList (检索条件)
         * @return 按顺序返回的多个结果
         * @throws IOException 调用方处理结果
         */
        public MultiSearchResponse.Item[] multiSearch(String index, List<SearchSourceBuilder> SSBList) throws IOException {
            MultiSearchRequest request = new MultiSearchRequest();
            for (SearchSourceBuilder ssb : SSBList) {
                log.info("query DSL:[{}]", ssb.toString());
                SearchRequest searchRequest = Requests.searchRequest(index).source(ssb);
                request.add(searchRequest);
            }
            MultiSearchResponse response = restClient.msearch(request, RequestOptions.DEFAULT);
            return response.getResponses();
        }
  • 相关阅读:
    ThinPHP v5.x安装初始化配置(项目实战)
    Bresenham快速画直线算法
    arm笔记之MOV
    Blackfin DSP的C语言优化之Circular Buffer
    Visual DSP定点数(fract)使用指南
    全局二值化
    Blackfin DSP学习心得与参考资料
    Linux网络配置
    一般方程与参数方程求直线交点
    一个改进的快速排序实现
  • 原文地址:https://www.cnblogs.com/yb38156/p/16451728.html
Copyright © 2020-2023  润新知