当前位置:

首页 > 编程开发 > springboot2+es7怎么使用RestHighLevelClient

springboot2+es7怎么使用RestHighLevelClient

由于spring和es的集成并不是特别友好,es的高低版本兼容问题、api更新频率高等问题,所以我选择是官网提供的原生Client(RestHighLevelClient),但又不想去关注es的配置类以及和spring的集成配置、jar包冲突等问题,所以使用spring-boot-starter-data-elasticsearch。一、引入依赖jarorg.springframework.bootspring-boot-starter-data-elasticsearch二、application.pr

本文目录

    由于spring和es的集成并不是特别友好,es的高低版本兼容问题、api更新频率高等问题,所以我选择是官网提供的原生Client(RestHighLevelClient),但又不想去关注es的配置类以及和spring的集成配置、jar包冲突等问题,所以使用spring-boot-starter-data-elasticsearch。

    一、引入依赖jar

            
                org.springframework.boot
                spring-boot-starter-data-elasticsearch
            

    二、application.properties配置

    spring.elasticsearch.rest.uris=http://127.0.0.1:9200,http://127.0.0.1:9201,http://127.0.0.1:9202
    spring.elasticsearch.rest.connection-timeout=5s
    spring.elasticsearch.rest.read-timeout=30s
    logging.level.org.springframework.data.convert.CustomConversions=error

    spring-boot-starter-data-elasticsearch中自动装配es的配置类:ElasticsearchRestClientAutoConfiguration、ElasticsearchRestClientProperties。

    ElasticsearchRestClientAutoConfiguration:

    @ConditionalOnClass({RestHighLevelClient.class})
    @ConditionalOnMissingBean({RestClient.class})
    @EnableConfigurationProperties({ElasticsearchRestClientProperties.class})
    public class ElasticsearchRestClientAutoConfiguration {
     
        @Configuration(
            proxyBeanMethods = false
        )
        @ConditionalOnMissingBean({RestHighLevelClient.class})
        static class RestHighLevelClientConfiguration {
            RestHighLevelClientConfiguration() {
            }
     
            @Bean
            RestHighLevelClient elasticsearchRestHighLevelClient(RestClientBuilder restClientBuilder) {
                return new RestHighLevelClient(restClientBuilder);
            }
        }
     
        @Configuration(
            proxyBeanMethods = false
        )
        @ConditionalOnMissingBean({RestClientBuilder.class})
        static class RestClientBuilderConfiguration {
            RestClientBuilderConfiguration() {
            }
     
            @Bean
            RestClientBuilderCustomizer defaultRestClientBuilderCustomizer(ElasticsearchRestClientProperties properties) {
                return new ElasticsearchRestClientAutoConfiguration.DefaultRestClientBuilderCustomizer(properties);
            }
     
            @Bean
            RestClientBuilder elasticsearchRestClientBuilder(ElasticsearchRestClientProperties properties, ObjectProvider builderCustomizers) {
                HttpHost[] hosts = (HttpHost[])properties.getUris().stream().map(this::createHttpHost).toArray((x$0) -> {
                    return new HttpHost[x$0];
                });
                RestClientBuilder builder = RestClient.builder(hosts);
                builder.setHttpClientConfigCallback((httpClientBuilder) -> {
                    builderCustomizers.orderedStream().forEach((customizer) -> {
                        customizer.customize(httpClientBuilder);
                    });
                    return httpClientBuilder;
                });
                builder.setRequestConfigCallback((requestConfigBuilder) -> {
                    builderCustomizers.orderedStream().forEach((customizer) -> {
                        customizer.customize(requestConfigBuilder);
                    });
                    return requestConfigBuilder;
                });
                builderCustomizers.orderedStream().forEach((customizer) -> {
                    customizer.customize(builder);
                });
                return builder;
            }
     
            private HttpHost createHttpHost(String uri) {
                try {
                    return this.createHttpHost(URI.create(uri));
                } catch (IllegalArgumentException var3) {
                    return HttpHost.create(uri);
                }
            }
     
            private HttpHost createHttpHost(URI uri) {
                if (!StringUtils.hasLength(uri.getUserInfo())) {
                    return HttpHost.create(uri.toString());
                } else {
                    try {
                        return HttpHost.create((new URI(uri.getScheme(), (String)null, uri.getHost(), uri.getPort(), uri.getPath(), uri.getQuery(), uri.getFragment())).toString());
                    } catch (URISyntaxException var3) {
                        throw new IllegalStateException(var3);
                    }
                }
            }
        }
    }

    ElasticsearchRestClientProperties: 

    @ConfigurationProperties(
        prefix = "spring.elasticsearch.rest"
    )
    public class ElasticsearchRestClientProperties {
        private List uris = new ArrayList(Collections.singletonList("http://localhost:9200"));
        private String username;
        private String password;
        private Duration connectionTimeout = Duration.ofSeconds(1L);
        private Duration readTimeout = Duration.ofSeconds(30L);
     
        public ElasticsearchRestClientProperties() {
        }
     
        public List getUris() {
            return this.uris;
        }
     
        public void setUris(List uris) {
            this.uris = uris;
        }
     
        public String getUsername() {
            return this.username;
        }
     
        public void setUsername(String username) {
            this.username = username;
        }
     
        public String getPassword() {
            return this.password;
        }
     
        public void setPassword(String password) {
            this.password = password;
        }
     
        public Duration getConnectionTimeout() {
            return this.connectionTimeout;
        }
     
        public void setConnectionTimeout(Duration connectionTimeout) {
            this.connectionTimeout = connectionTimeout;
        }
     
        public Duration getReadTimeout() {
            return this.readTimeout;
        }
     
        public void setReadTimeout(Duration readTimeout) {
            this.readTimeout = readTimeout;
        }
    }

    三、使用

    ES基本操作持久层

    /**
     * es持久层
     *
     * @author yangzihe
     * @date 2022/1/24
     */
    @Repository
    @Slf4j
    public class EsRepository {
     
        @Resource
        private RestHighLevelClient highLevelClient;
     
        /**
         * 判断索引是否存在
         */
        public boolean existIndex(String index) {
            try {
                return highLevelClient.indices().exists(new GetIndexRequest(index), RequestOptions.DEFAULT);
            } catch (IOException e) {
                log.error("es持久层异常!index={}", index, e);
            }
            return Boolean.FALSE;
        }
     
        /**
         * 创建索引
         */
        public boolean createIndex(String index, Map columnMap) {
            if (existIndex(index)) {
                return Boolean.FALSE;
            }
     
            CreateIndexRequest request = new CreateIndexRequest(index);
            if (columnMap != null && columnMap.size() > 0) {
                Map source = new HashMap<>();
                source.put("properties", columnMap);
                request.mapping(source);
            }
            try {
                highLevelClient.indices().create(request, RequestOptions.DEFAULT);
                return Boolean.TRUE;
            } catch (IOException e) {
                log.error("es持久层异常!index={}, columnMap={}", index, columnMap, e);
            }
            return Boolean.FALSE;
        }
     
        /**
         * 删除索引
         */
        public boolean deleteIndex(String index) {
            try {
                if (existIndex(index)) {
                    AcknowledgedResponse response = highLevelClient.indices().delete(new DeleteIndexRequest(index), RequestOptions.DEFAULT);
                    return response.isAcknowledged();
                }
            } catch (Exception e) {
                log.error("es持久层异常!index={}", index, e);
            }
            return Boolean.FALSE;
        }
     
        /**
         * 数据新增
         */
        public boolean insert(String index, String jsonString) {
            IndexRequest indexRequest = new IndexRequest(index);
     
            indexRequest.id(new Snowflake().nextIdStr());
            indexRequest.source(jsonString, XContentType.JSON);
     
            try {
                log.info("indexRequest={}", indexRequest);
                IndexResponse indexResponse = highLevelClient.index(indexRequest, RequestOptions.DEFAULT);
                log.info("indexResponse={}", indexResponse);
                return Boolean.TRUE;
            } catch (IOException e) {
                log.error("es持久层异常!index={}, jsonString={}", index, jsonString, e);
            }
            return Boolean.FALSE;
        }
     
        /**
         * 数据更新,可以直接修改索引结构
         */
        public boolean update(String index, Map dataMap) {
            UpdateRequest updateRequest = new UpdateRequest(index, dataMap.remove("id").toString());
            updateRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
            updateRequest.doc(dataMap);
            try {
                highLevelClient.update(updateRequest, RequestOptions.DEFAULT);
            } catch (IOException e) {
                log.error("es持久层异常!index={}, dataMap={}", index, dataMap, e);
                return Boolean.FALSE;
            }
            return Boolean.TRUE;
        }
     
        /**
         * 删除数据
         */
        public boolean delete(String index, String id) {
            DeleteRequest deleteRequest = new DeleteRequest(index, id);
            try {
                highLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
            } catch (IOException e) {
                log.error("es持久层异常!index={}, id={}", index, id, e);
                return Boolean.FALSE;
            }
            return Boolean.TRUE;
        }
     
    }

    ES查询持久层

    /**
     * es查询持久层
     *
     * @author yangzihe
     * @date 2022/1/25
     */
    @Repository
    @Slf4j
    public class EsSearchRepository {
     
        @Resource
        private RestHighLevelClient highLevelClient;
     
        /**
         * 分页查询
         *
         * @param queryPO 分页查询对象
         *
         * @return 分页查询结果
         */
        public EsQueryRespPO> searchPage(EsQueryReqPO queryPO) {
            // 默认分页参数设置
            if (queryPO.getPageNum() == null) {
                queryPO.setPageNum(1);
            }
            if (queryPO.getPageSize() == null) {
                queryPO.setPageSize(10);
            }
     
            // 设置索引
            SearchRequest searchRequest = new SearchRequest(queryPO.getIndex());
     
            // 封装查询源对象
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            searchRequest.source(sourceBuilder);
     
            // 查询条件
            sourceBuilder.query(queryPO.getQuery());
     
            // 排序字段
            if (StringUtils.isNotBlank(queryPO.getSortField()) && queryPO.getSort() != null) {
                FieldSortBuilder order = new FieldSortBuilder(queryPO.getSortField()).order(queryPO.getSort());
                sourceBuilder.sort(order);
            }
     
            // 开始行数,默认0
            sourceBuilder.from((queryPO.getPageNum() - 1) * queryPO.getPageSize());
            // 页大小,默认10
            sourceBuilder.size(queryPO.getPageSize());
     
            // 查询结果
            SearchResponse searchResponse = null;
            try {
                // log.info("es查询请求对象:searchRequest={}", searchRequest);
                log.info("es查询请求对象source:sourceBuilder={}", searchRequest.source());
                // 执行搜索
                searchResponse = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);
                log.info("es查询响应结果:searchResponse={}", searchResponse);
            } catch (IOException e) {
                log.error("es查询,IO异常!searchRequest={}", searchRequest, e);
                // 异常处理
                return EsQueryRespPO.error("es查询,IO异常!");
            }
     
            if (RestStatus.OK.equals(searchResponse.status())) {
                // 解析对象
                SearchHit[] hits = searchResponse.getHits().getHits();
                // 获取source
                List> sourceList = Arrays.stream(hits).map(SearchHit::getSourceAsMap).collect(Collectors.toList());
                long totalHits = searchResponse.getHits().getTotalHits().value;
                return EsQueryRespPO.success(sourceList, queryPO.getPageNum(), queryPO.getPageSize(), totalHits);
            } else {
                log.error("es查询返回的状态码异常!searchResponse.status={}, searchRequest={}", searchResponse.status(), searchRequest);
                return EsQueryRespPO.error("es查询返回的状态码异常!");
            }
        }
     
        /**
         * 聚合的分页查询
         *
         * @param queryPO 查询请求对象
         *
         * @return 聚合分页查询结果
         */
        public EsQueryRespPO searchAggregation(EsQueryReqPO queryPO) {
            // 设置索引
            SearchRequest searchRequest = new SearchRequest(queryPO.getIndex());
     
            // 封装查询源对象
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            searchRequest.source(sourceBuilder);
     
            // 查询条件
            sourceBuilder.query(queryPO.getQuery());
     
            // 排序字段
            if (StringUtils.isNotBlank(queryPO.getSortField()) && queryPO.getSort() != null) {
                FieldSortBuilder order = new FieldSortBuilder(queryPO.getSortField()).order(queryPO.getSort());
                sourceBuilder.sort(order);
            }
     
            // 页大小0,只返回聚合结果
            sourceBuilder.size(0);
     
            // 设置聚合查询,可以设置多个聚合查询条件,只要聚合查询命名不同就行
            // 聚合分组条件, group by
            sourceBuilder.aggregation(queryPO.getTermsAggregation());
            // 聚合统计条件, count分组后的数据,计算分组后的总大小
            sourceBuilder.aggregation(queryPO.getCardinalityAggregation());
     
            // 查询结果
            SearchResponse searchResponse = null;
            try {
                // log.info("es查询请求对象:searchRequest={}", searchRequest);
                log.info("es查询请求对象source:sourceBuilder={}", searchRequest.source());
                // 执行搜索
                searchResponse = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);
                log.info("es查询响应结果:searchResponse={}", searchResponse);
            } catch (IOException e) {
                log.error("es查询,IO异常!searchRequest={}", searchRequest, e);
                return EsQueryRespPO.error("es查询,IO异常!");
            }
     
            if (RestStatus.OK.equals(searchResponse.status())) {
                // 解析对象
                Aggregations aggregations = searchResponse.getAggregations();
     
                long docTotal = searchResponse.getHits().getTotalHits().value;
     
                // 遍历terms聚合结果
                Terms terms = aggregations.get(queryPO.getTermsAggregation().getName());
                List bucketList = terms.getBuckets().stream().map(bucket -> {
                    String key = bucket.getKeyAsString();
                    long docCount = bucket.getDocCount();
                    return new AggregationBucketPO(key, docCount, docTotal);
                }).collect(Collectors.toList());
     
                // 总数量
                Cardinality cardinality = aggregations.get(queryPO.getCardinalityAggregation().getName());
                long totalHits = cardinality.getValue();
     
                return EsQueryRespPO.success(bucketList, queryPO.getPageNum(), queryPO.getPageSize(), totalHits);
            } else {
                log.error("es查询返回的状态码异常!searchResponse.status={}, searchRequest={}", searchResponse.status(), searchRequest);
                return EsQueryRespPO.error("es查询返回的状态码异常!");
            }
        }
    }

    其中,EsQueryReqPO、EsQueryRespPO、AggregationBucketPO等类如下:

    /**
     * es查询请求对象
     */
    @Data
    public class EsQueryReqPO {
     
        /**
         * 索引名
         */
        String[] index;
     
        /**
         * 查询条件
         */
        QueryBuilder query;
     
        /**
         * 排序字段
         */
        String sortField;
     
        /**
         * 排序方式 SortOrder.ASC、SortOrder.DESC
         */
        SortOrder sort;
     
        /**
         * 页数
         */
        private Integer pageNum;
     
        /**
         * 页大小
         */
        private Integer pageSize;
     
        /**
         * 聚合分组条件, group by
         */
        private TermsAggregationBuilder termsAggregation;
     
        /**
         * 聚合统计条件, count分组后的数据
         */
        private CardinalityAggregationBuilder cardinalityAggregation;
    }
    /**
     * es分页响应对象
     *
     * @author yangzihe
     * @date 2022/1/25
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class EsQueryRespPO {
     
        /**
         * 是否成功
         */
        private Boolean success;
     
        /**
         * 信息
         */
        private String message;
     
        /**
         * 页数
         */
        private Integer pageNum;
     
        /**
         * 页大小
         */
        private Integer pageSize;
     
        /**
         * 总大小
         */
        private Long totalSize;
     
        /**
         * 数据
         */
        private List sourceList;
     
        public static  EsQueryRespPO success(List sourceList, Integer pageNum, Integer pageSize,
                                                   Long totalSize) {
            EsQueryRespPO esQueryRespPO = new EsQueryRespPO<>();
            esQueryRespPO.setSuccess(true);
            esQueryRespPO.setSourceList(sourceList);
            esQueryRespPO.setPageNum(pageNum);
            esQueryRespPO.setPageSize(pageSize);
            esQueryRespPO.setTotalSize(totalSize);
            return esQueryRespPO;
        }
     
        public static EsQueryRespPO error() {
            EsQueryRespPO esQueryRespPO = new EsQueryRespPO();
            esQueryRespPO.setSuccess(false);
            esQueryRespPO.setMessage("es查询异常");
            return esQueryRespPO;
        }
     
        public static EsQueryRespPO error(String message) {
            EsQueryRespPO esQueryRespPO = new EsQueryRespPO();
            esQueryRespPO.setSuccess(false);
            esQueryRespPO.setMessage(message);
            return esQueryRespPO;
        }
     
    }
    /**
     * 聚合桶对象
     *
     * @author yangzihe
     * @date 2022/1/26
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class AggregationBucketPO {
     
        /**
         * 聚合Bucket的key名
         */
        private String key;
     
        /**
         * 聚合Bucket的文档数量
         */
        private Long docCount;
     
        /**
         * 文档总数量
         */
        private Long docTotal;
     
    }

    ES多级(二级)聚合分桶查询

    import com.yy.armor.manager.common.exception.EsException;
    import com.yy.armor.manager.persist.es.po.AggregationBucketPO;
    import com.yy.armor.manager.persist.es.po.EsMultiAggregationReqPO;
     
    import java.io.IOException;
    import java.util.List;
    import java.util.stream.Collectors;
    import javax.annotation.Resource;
     
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.collections4.CollectionUtils;
    import org.apache.commons.lang3.StringUtils;
    import org.apache.pulsar.shade.org.apache.commons.compress.utils.Lists;
    import org.elasticsearch.action.search.SearchRequest;
    import org.elasticsearch.action.search.SearchResponse;
    import org.elasticsearch.client.RequestOptions;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.elasticsearch.rest.RestStatus;
    import org.elasticsearch.search.aggregations.AggregationBuilders;
    import org.elasticsearch.search.aggregations.bucket.terms.Terms;
    import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
    import org.elasticsearch.search.builder.SearchSourceBuilder;
    import org.elasticsearch.search.sort.FieldSortBuilder;
    import org.springframework.stereotype.Repository;
     
     
    @Repository
    @Slf4j
    public class EsSearchRepository {
     
        @Resource
        private RestHighLevelClient highLevelClient;
     
     
        /**
         * 多级聚合查询(二级聚合)
         *
         * @param reqPO 查询请求对象
         *
         * @return 聚合查询结果
         */
        public List searchMultiAggregation(EsMultiAggregationReqPO reqPO) {
            // 设置索引
            SearchRequest searchRequest = new SearchRequest(reqPO.getIndex());
     
            // 封装查询源对象
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            searchRequest.source(sourceBuilder);
     
            // 查询条件
            sourceBuilder.query(reqPO.getQuery());
     
            // 排序字段
            if (StringUtils.isNotBlank(reqPO.getSortField()) && reqPO.getSort() != null) {
                FieldSortBuilder order = new FieldSortBuilder(reqPO.getSortField()).order(reqPO.getSort());
                sourceBuilder.sort(order);
            }
     
            // 页大小0,只返回聚合结果
            sourceBuilder.size(0);
     
            // 聚合分桶。创建terms桶聚合,聚合名字=terms_by_XXX, 字段=XXX
            TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("terms_by_" + reqPO.getField()).field(reqPO.getField());
            if (reqPO.getFieldSize() != null) {
                termsAggregationBuilder.size(reqPO.getFieldSize());
            }
            // 二级聚合分桶
            TermsAggregationBuilder subTermsAggregationBuilder = AggregationBuilders.terms("terms_by_" + reqPO.getSubField()).field(reqPO.getSubField());
            if (reqPO.getSubFieldSize() != null) {
                subTermsAggregationBuilder.size(reqPO.getSubFieldSize());
            }
            termsAggregationBuilder.subAggregation(subTermsAggregationBuilder);
     
            // 聚合分组条件
            sourceBuilder.aggregation(termsAggregationBuilder);
     
            // 查询结果
            SearchResponse searchResponse = null;
            try {
                log.info("es查询请求对象source:sourceBuilder={}", searchRequest.source());
                // 执行搜索
                searchResponse = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);
                log.info("es查询响应结果:searchResponse={}", searchResponse);
            } catch (IOException e) {
                log.error("es查询,IO异常!searchRequest={}", searchRequest, e);
                throw new EsException("es查询,IO异常!");
            }
     
            if (RestStatus.OK.equals(searchResponse.status())) {
                // 遍历terms聚合结果
                Terms terms = searchResponse.getAggregations().get(termsAggregationBuilder.getName());
                List bucketList = terms.getBuckets().stream().map(bucket -> {
                    // 一级聚合分桶的数据
                    String key = bucket.getKeyAsString();
                    long docCount = bucket.getDocCount();
                    // 二级聚合分桶的数据
                    Terms subTerms = bucket.getAggregations().get(subTermsAggregationBuilder.getName());
                    List subBucketList = convertTerms(subTerms);
                    return new AggregationBucketPO(key, docCount, subBucketList);
                }).collect(Collectors.toList());
     
                return bucketList;
            } else {
                log.error("es查询返回的状态码异常!searchResponse.status={}, searchRequest={}", searchResponse.status(), searchRequest);
                throw new EsException("es查询返回的状态码异常!");
            }
        }
     
        private List convertTerms(Terms terms) {
            if (CollectionUtils.isEmpty(terms.getBuckets())) {
                return Lists.newArrayList();
            }
     
            return terms.getBuckets().stream().map(bucket -> {
                String key = bucket.getKeyAsString();
                long docCount = bucket.getDocCount();
                return new AggregationBucketPO(key, docCount);
            }).collect(Collectors.toList());
        }
    }

    其中,EsMultiAggregationReqPO、AggregationBucketPO类如下:

    @Data
    public class EsMultiAggregationReqPO {
        
        /**
         * 索引名
         */
        String[] index;
     
        /**
         * 查询条件
         */
        QueryBuilder query;
     
        /**
         * 聚合分桶字段
         */
        private String field;
     
        /**
         * 二级聚合分桶字段
         */
        private String subField;
     
        /**
         * 聚合分桶大小,非必传
         */
        private Integer fieldSize;
     
        /**
         * 二级聚合分桶大小,非必传
         */
        private Integer subFieldSize;
     
        /**
         * 排序字段,非必传
         */
        String sortField;
     
        /**
         * 排序方式 SortOrder.ASC、SortOrder.DESC,非必传
         */
        SortOrder sort;
    }
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class AggregationBucketPO {
        /**
         * 聚合Bucket的key名
         */
        private String key;
     
        /**
         * 聚合Bucket的文档数量
         */
        private Long docCount;
     
        /**
         * 子桶集合
         */
        private List subBucketList;
     
        public AggregationBucketPO(String key, Long docCount) {
            this.key = key;
            this.docCount = docCount;
        }
    }

    二级聚合分桶测试代码 

        @PostConstruct
        private void init() {
            // 查询对象的封装
            EsMultiAggregationReqPO reqPO = new EsMultiAggregationReqPO();
     
            reqPO.setIndex(new String[]{"test_log"});
     
            List ids = Lists.newArrayList();
            ids.add(140L);
            ids.add(141L);
            ids.add(142L);
            QueryBuilder queryBuilder4 = QueryBuilders.termsQuery("eventId", ids);
            BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery().must(queryBuilder4);
            reqPO.setQuery(queryBuilder);
     
            reqPO.setField("eventId");
            reqPO.setFieldSize(9999);
            reqPO.setSubField("riskFlag");
     
            // 执行查询
            List esQueryRespPO = searchMultiAggregation(reqPO);
            System.out.println("esQueryRespPO=" + esQueryRespPO);
        }

    其它

    如果没有用spring-boot-starter-data-elasticsearch来自动注入es组件,那么需要自己做es client的注入,es配置类如下:

    /**
     * @author yangzihe
     * @date 2022/1/25
     */
    @Configuration
    public class EsClientConfig {
     
        @Value("${spring.elasticsearch.rest.uris}")
        private List uris;
     
        @Bean
        public RestHighLevelClient restHighLevelClient() {
            List httpHostList = uris.stream().map(HttpHost::create).collect(Collectors.toList());
            HttpHost[] httpHost = new HttpHost[uris.size()];
            httpHostList.toArray(httpHost);
            RestClientBuilder clientBuilder = RestClient.builder(httpHost);
            return new RestHighLevelClient(clientBuilder);
        }
     
    }

    Snowflake是hutool包里的,导包:

            
            
                cn.hutool
                hutool-all
                5.7.14
            

    聚合查询的测试用例:

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest(classes = StartApplication.class)
    public class EsTest {
     
        @Resource
        private EsSearchRepository esSearchRepository;
     
        @Test
        public void testSearchAggregation() {
            // 查询对象的封装
            EsQueryReqPO queryPO = new EsQueryReqPO();
            queryPO.setIndex(new String[]{"yzh2", "yzh3"});
            queryPO.setPageNum(1);
            queryPO.setPageSize(10);
     
            // 时间戳范围
            QueryBuilder queryBuilder1 = QueryBuilders.rangeQuery("timestamp")
                .from(System.currentTimeMillis() - 1000)
                .to(System.currentTimeMillis());
            // 登录标识
            QueryBuilder queryBuilder2 = QueryBuilders.termQuery("name", "yang");
            BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery().must(queryBuilder1).must(queryBuilder2);
            queryPO.setQuery(queryBuilder);
     
            // 根据userName分组。创建terms桶聚合,聚合名字=terms_by_userName, 字段=payload.userName.keyword
            TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders
                .terms("terms_by_userName").field("payload.userName.keyword");
            termsAggregationBuilder.size(queryPO.getPageSize() * queryPO.getPageNum());
            termsAggregationBuilder.subAggregation(new BucketSortPipelineAggregationBuilder("bucket_field", null)
                .from((queryPO.getPageNum() - 1) * queryPO.getPageSize()).size(queryPO.getPageSize()));
            queryPO.setTermsAggregation(termsAggregationBuilder);
     
            // 根据userName聚合count统计. cardinality名=count_userName, 字段=payload.userName.keyword
            CardinalityAggregationBuilder cardinalityAggregationBuilder = AggregationBuilders
                .cardinality("count_userName").field("payload.userName.keyword");
            queryPO.setCardinalityAggregation(cardinalityAggregationBuilder);
     
            // 执行查询
            EsQueryRespPO esQueryRespPO = esSearchRepository.searchAggregation(queryPO);
        }
    }
    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 es
    相关文章 更多
    如何使用PHP和ES6进行现代化Web开发
    如何使用PHP和ES6进行现代化Web开发

    随着Web应用程序的复杂性和用户需求的增加,现代化Web开发变得越来越重要。使用PHP和ES6可以为开发人员提供许多有用的工具,这些工具可以帮助他们更有效地编写、测试和维护现代化的Web应用程序。本文将介绍如何使用PHP和ES6进行现代化Web开发,包括最佳实践、工具和技巧。如果你是一名开发人员,而且想要提高你的Web开发技能,那么这篇文章将对你有所启发。一

    springBoot项目常用目录有哪些
    springBoot项目常用目录有哪些

    springBoot项目常用目录springBoot项目的目录结构及名规范介绍基于SpringBoot开发时的目录结构及命名规范,通过介绍能够为你解决,在实际项目中如何规划目录结构?如何命名目录更规范?各个目录分别代表什么含义?等三个问题。目录说明servicex//项目名|-admin-ui//管理服务前端代码(一般将UI和SERVICE放到一个工程中,便于管理)|-servicex-auth//模块1|-servicex-common//模块2|-servicex-gateway//模块3|-serv

    解析SpringBoot和SpringMVC之间的异同
    解析SpringBoot和SpringMVC之间的异同

    解析SpringBoot和SpringMVC之间的异同SpringBoot和SpringMVC是Java领域中非常重要的开发框架。虽然它们都属于Spring框架的一部分,但是在使用和功能上有一些明显的区别。本文将对SpringBoot和SpringMVC进行比较,解析它们之间的异同。首先,让我们来了解一下SpringBoot。SpringBo

    探索SpringCloud和SpringBoot在微服务领域的不同应用方式
    探索SpringCloud和SpringBoot在微服务领域的不同应用方式

    近年来,随着云计算和分布式架构的兴起,微服务架构的应用越来越广泛。而SpringCloud和SpringBoot作为Java开发中的两个重要框架,对于微服务的实现起到了重要的作用。然而,很多人对于它们在微服务领域的不同应用方式还存在一定的疑惑。本文将从不同的角度探索SpringCloud和SpringBoot在微服务中的应用方式。首先,我们来了解一下Spri

    SpringBoot和SpringMVC有何区别?
    SpringBoot和SpringMVC有何区别?

    SpringBoot与SpringMVC的不同之处在哪里?SpringBoot和SpringMVC是两个非常流行的Java开发框架,用于构建Web应用程序。尽管它们经常分别被使用,但它们之间的不同之处也是很明显的。首先,SpringBoot可以被看作是一个Spring框架的扩展或者增强版。它旨在简化Spring应用程序的初始化和配置过程,以帮助开发人

    比较SpringBoot和SpringMVC的异同
    比较SpringBoot和SpringMVC的异同

    SpringBoot和SpringMVC都是Java开发中常用的框架,但它们之间有一些明显的差异。本文将探究这两个框架的特点和用途,并对它们的差异进行比较。首先,我们来了解一下SpringBoot。SpringBoot是由Pivotal团队开发的,它旨在简化基于Spring框架的应用程序的创建和部署。它提供了一种快速、轻量级的方式来构建独立的、可执行

    SpringBoot与SpringMVC的不同点是什么?
    SpringBoot与SpringMVC的不同点是什么?

    SpringBoot和SpringMVC是Java开发中常用的两个框架,它们都是由Spring框架所提供的,但在功能和使用方式上有着一些区别。本文将分别介绍SpringBoot和SpringMVC的特点和区别。一、SpringBoot的特点:简化配置:SpringBoot通过约定优于配置的原则,大大简化了项目的配置过程。它可以自动配置项目所需要的参数,开发人

    比较和选择指南:SpringCloud与SpringBoot的功能比较
    比较和选择指南:SpringCloud与SpringBoot的功能比较

    SpringCloud和SpringBoot是目前Java领域中最热门的开源框架,它们分别提供了一套完善的微服务架构和快速构建应用程序的解决方案。本文将对它们的功能进行比较,并给出选择指南,以帮助读者了解它们的优势和适用场景。SpringBoot是一个用于开发Java应用程序的框架,它提供了一个简化的开发流程,集成了大量常用的功能和组件,减少了开发者的工作量

    SpringCloud与SpringBoot:分析它们之间的相似与不同
    SpringCloud与SpringBoot:分析它们之间的相似与不同

    深入剖析SpringCloud和SpringBoot的异同引言:在构建企业级应用程序时,Spring框架已经成为开发者们的首选。它提供了一种简单而强大的方式来构建独立于平台的应用程序。Spring框架由两个核心模块组成:SpringBoot和SpringCloud。虽然它们都可以帮助开发者快速搭建应用程序,但它们的目标和用途存在一些差异。本文将深入剖析Spr

    从架构角度看SpringCloud与SpringBoot的差异
    从架构角度看SpringCloud与SpringBoot的差异

    从架构角度看SpringCloud与SpringBoot的差异引言:在当今的互联网时代,构建分布式系统已经成为了一种必要的需求。而SpringBoot和SpringCloud正是为了满足这个需求而诞生的。尽管它们都是由Spring框架所提供的解决方案,但从架构角度来看,它们存在着一些重要的差异。本文将从架构的角度出发,对SpringBoot和SpringCl

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。