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;
    }
相关推荐
Coder_Boy_4 小时前
基于SpringAI的在线考试系统-0到1全流程研发:DDD、TDD与CICD协同实践
java·人工智能·spring boot·架构·ddd·tdd
卓怡学长5 小时前
m115乐购游戏商城系统
java·前端·数据库·spring boot·spring·游戏
未若君雅裁6 小时前
SpringAI基础入门
java·spring boot·ai
JingAi_jia9177 小时前
SpringBoot Jackson 序列化
spring boot·jackson·数据序列化·serializer
CCPC不拿奖不改名7 小时前
两种完整的 Git 分支协作流程
大数据·人工智能·git·python·elasticsearch·搜索引擎·自然语言处理
a努力。7 小时前
字节Java面试被问:TCP的BBR拥塞控制算法原理
java·开发语言·python·tcp/ip·elasticsearch·面试·职场和发展
Elastic 中国社区官方博客8 小时前
使用瑞士风格哈希表实现更快的 ES|QL 统计
大数据·数据结构·sql·elasticsearch·搜索引擎·全文检索·散列表
qq_12498707538 小时前
基于小程序中医食谱推荐系统的设计(源码+论文+部署+安装)
java·spring boot·后端·微信小程序·小程序·毕业设计·计算机毕业设计
Coder_Boy_8 小时前
基于SpringAI的在线考试系统-阅卷评分模块时序图
java·人工智能·spring boot
牧小七9 小时前
SpringBoot使用validation
spring boot