springboot 接入Elasticsearch的聚合查询

首先需要引入maven依赖

java 复制代码
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.12.1</version>
        </dependency>

增加es的配置文件,示例:

XML 复制代码
#es7.x
search:
  elastic:
    datalake:
      scheme: https
      host: asd-test.xxxx.net.cn
      port: 9200
      user: admin
      password: 123456
    index:
      fdt-rule: xxxxxxxxx

代码配置注册客户端

java 复制代码
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ElasticsearchConfig {

    @Value("${search.elastic.datalake.scheme}")
    private String esScheme;

    @Value("${search.elastic.datalake.host}")
    private String esHost;

    @Value("${search.elastic.datalake.port}")
    private int esPort;

    @Value("${search.elastic.datalake.user}")
    private String esUser;

    @Value("${search.elastic.datalake.password}")
    private String esPassword;

    private final Logger LOGGER = LoggerFactory.getLogger(getClass());

    @Bean
    public RestHighLevelClient client() {
        LOGGER.info("initialize elasticSearch7.x----eHost:{},esPort:{}", esHost, esPort);

        RestClientBuilder builder = RestClient.builder(
                new HttpHost(this.esHost, this.esPort, this.esScheme)
        );

        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        // 用户名、密码
        credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(this.esUser, this.esPassword));

        builder.setHttpClientConfigCallback(httpClientBuilder ->
                httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)
        );

        return new RestHighLevelClient(builder);
    }


}
java 复制代码
/**
     * 执行es查询
     *
     * @param req          参数
     * @param groupByField 分组聚合字段
     * @param indexName    索引名称
     * @return SearchResponse
     */
    @SneakyThrows
    private SearchResponse getSearchResponse(DsrIncentiveSalaryCommonRequest req, String groupByField, String indexName) {
        // 创建搜索请求
        SearchRequest searchRequest = new SearchRequest(indexName);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // 创建布尔查询
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        // 来源不为空,则过滤工号
        if (DATA_TYPE_ONE.equals(req.getSourceEmp())) {
            boolQuery.must(getQueryBuilder(req.getEmpCode(), ADVISER_CODE));
        }
        if (DATA_TYPE_TWO.equals(req.getSourceEmp())) {
            boolQuery.must(getQueryBuilder(req.getEmpCode(), EMP_CODE));
        }
        // 其他筛选条件
        if (CollectionUtils.isNotEmpty(req.getCustNumList())) {
            List<String> custNumList = req.getCustNumList().stream().filter(StringUtils::isNotBlank).collect(Collectors.toList());
            boolQuery.must(QueryBuilders.termsQuery(CUST_NUM, custNumList));
        }
        if (CollectionUtils.isNotEmpty(req.getRequirementIdList())) {
            List<String> requirementIdList = req.getRequirementIdList().stream().filter(StringUtils::isNotBlank).collect(Collectors.toList());
            boolQuery.must(QueryBuilders.termsQuery(REQUIREMENT_ID, requirementIdList));
        }
        if (CollectionUtils.isNotEmpty(req.getRequirementStatusList())) {
            List<Integer> requirementStatusList = req.getRequirementStatusList().stream().filter(Objects::nonNull).collect(Collectors.toList());
            boolQuery.must(QueryBuilders.termsQuery("requirementStatus", requirementStatusList));
        }
        if (CollectionUtils.isNotEmpty(req.getSkuUniqList())) {
            List<String> skuUniqList = req.getSkuUniqList().stream().filter(StringUtils::isNotBlank).collect(Collectors.toList());
            boolQuery.must(QueryBuilders.termsQuery(UNIQUE_CODE, skuUniqList));
        }
        if (CollectionUtils.isNotEmpty(req.getTaskSubIdList())) {
            List<String> taskSubIdList = req.getTaskSubIdList().stream().filter(StringUtils::isNotBlank).collect(Collectors.toList());
            boolQuery.must(QueryBuilders.termsQuery(TASK_SUB_ID, taskSubIdList));
        }
        if (StringUtils.isNotBlank(req.getRequirementStartTime()) && StringUtils.isNotBlank(req.getRequirementEndTime())) {
            if (REAL_INDEX.equals(indexName)) {
                boolQuery.must(QueryBuilders.rangeQuery("requirementExecutedDate")
                        .lte(req.getRequirementEndTime())
                        .gte(req.getRequirementStartTime())
                );
            } else if (CollectionUtils.isEmpty(req.getRequirementIdList()) && CollectionUtils.isEmpty(req.getTaskSubIdList())) {
                boolQuery.must(QueryBuilders.rangeQuery("requirementStartTime")
                        .lte(req.getRequirementEndTime()));
                boolQuery.must(QueryBuilders.rangeQuery("requirementEndTime")
                        .gte(req.getRequirementStartTime()));
            }
        }
        searchSourceBuilder.query(boolQuery);

        // 构建聚合
        SumAggregationBuilder sumAggregation = AggregationBuilders.sum(TOTAL_VALUE).field("totalSalary");
        // 根据数据来源分别计算不同数据来源的激励积分,默认直接统计所有
        if (DATA_TYPE_ONE.equals(req.getSourceEmp())) {
            sumAggregation = AggregationBuilders.sum(TOTAL_VALUE)
                    .script(new Script("if (doc['adviserRatio'].size() > 0) { return doc['adviserRatio'].value * doc['totalSalary'].value; } else { return 0; }"));
        } else if (DATA_TYPE_TWO.equals(req.getSourceEmp())) {
            sumAggregation = AggregationBuilders.sum(TOTAL_VALUE)
                    .script(new Script("if (doc['dsrRatio'].size() > 0) { return doc['dsrRatio'].value * doc['totalSalary'].value; } else { return 0; }"));
        }

        TermsAggregationBuilder termsAgg = AggregationBuilders.terms(groupByField)
                .field(groupByField)
                .subAggregation(sumAggregation);
        searchSourceBuilder.aggregation(termsAgg).size(0);

        searchRequest.source(searchSourceBuilder);
        // 执行查询
        return client.search(searchRequest, RequestOptions.DEFAULT);
    }

    /**
     * 解析es查询结果
     *
     * @param searchResponse es查询结果
     * @param groupByField   分组字段
     * @return Map<String, BigDecimal>
     */
    private Map<String, BigDecimal> getEsResultMap(SearchResponse searchResponse, String groupByField) {
        Map<String, BigDecimal> salaryMap = new HashMap<>();
        // 通过分组字段获取聚合结果
        ParsedTerms parsedTerms = searchResponse.getAggregations().get(groupByField);
        for (Terms.Bucket bucket : parsedTerms.getBuckets()) {
            Aggregation totalValue = bucket.getAggregations().getAsMap().get(TOTAL_VALUE);
            if (totalValue instanceof ParsedSum) {
                ParsedSum parsedSum = (ParsedSum) totalValue;
                salaryMap.put(bucket.getKeyAsString(), BigDecimal.valueOf(parsedSum.getValue()));
            }
        }
        return salaryMap;
    }
相关推荐
bluetata3 小时前
在 Spring Boot 中使用 Amazon Textract 从图像中提取文本
java·spring boot·后端
Elasticsearch4 小时前
如何使用 LangChain 和 Elasticsearch 构建 agent 知识库
elasticsearch
CodeAmaz4 小时前
Elasticsearch 聚合(Aggregations)详解
elasticsearch·aggregation·聚合
电商API&Tina4 小时前
【电商API接口】多电商平台数据API接入方案(附带实例)
运维·开发语言·数据库·chrome·爬虫·python·jenkins
Andy工程师4 小时前
Netty 与 Spring Boot + HTTP 客户端(如 RestTemplate、WebClient)应用场景区别
spring boot·后端·http
ProgrammingWay5 小时前
ES常用API总结
elasticsearch·全文检索
czlczl200209255 小时前
实战:基于 MyBatis-Plus 实现无感知的“数据权限”自动过滤
spring boot·mybatis
Dxy12393102166 小时前
Elasticsearch 8.13.4 关键词如何高亮显示
大数据·elasticsearch
李迟6 小时前
2025年12月个人工作生活总结
大数据·elasticsearch·生活