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;
    }
相关推荐
阿丰资源9 小时前
java项目(附资料)-基于SpringBoot+MyBatisPlus+MySQL+Layui的药品管理系统
java·spring boot·mysql
indexsunny9 小时前
互联网大厂Java面试实战:从Spring Boot到微服务架构的深度探讨
java·数据库·spring boot·安全·微服务·监控·面试实战
宸津-代码粉碎机10 小时前
Spring Boot 4.0 实战技巧全解析
java·大数据·spring boot·后端·python
aq553560011 小时前
Laravel10.X核心特性全解析
java·开发语言·spring boot·后端
彭于晏Yan11 小时前
基于iText7的动态PDF生成技术方案
spring boot·pdf
ACGkaka_11 小时前
ES 学习(九)从文本到词元:分词器如何“拆解“你的数据
大数据·学习·elasticsearch
常利兵11 小时前
Spring Boot配置diff:解锁配置管理新姿势
java·spring boot·后端
卓怡学长12 小时前
w1基于springboot高校学生评教系统
java·spring boot·tomcat·maven·intellij-idea
Elastic 中国社区官方博客12 小时前
如何使用 LogsDB 降低 Elasticsearch 日志存储成本
大数据·运维·数据库·elasticsearch·搜索引擎·全文检索·可用性测试
A__tao12 小时前
一键实现 SQL 转 Elasticsearch Mapping(支持字段注释 + meta 描述)
数据库·sql·elasticsearch