java 使用RestHighLevelClient 请求es聚合数据

java 使用RestHighLevelClient 查询es聚合数据

使用Java请求es,使用RestHighLevelClient 进行es聚合请求查询,ES聚合嵌套参数拼接,就好处理了,拼接好查询参数和聚合参数,就直接请求了

代码:

相关引用和参数类代码关联《使用RestHighLevelClient 请求ES数据》

1,参数拼接

import org.apache.commons.collections4.ListUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.elasticsearch.script.Script;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.elasticsearch.search.aggregations.bucket.range.DateRangeAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.range.RangeAggregationBuilder;
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregatorBuilders;
import org.elasticsearch.search.aggregations.pipeline.bucketscript.BucketScriptPipelineAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.joda.time.DateTimeZone;

import java.util.List;
import java.util.Map;

public class StrTermNextScript {
 
    /**
     *  字符型的拼接
     *   第一层用 searchSourceBuilder 加
     */
    public static void joinEsStrAggs(Map<String,Object> aggsMap, SearchSourceBuilder searchSourceBuilder) {
        Map<String,Object> aggsNameMap = (Map<String, Object>) aggsMap.get("aggs");
        AggregationBuilder aggregationBuilder;

        for (Map.Entry name : aggsNameMap.entrySet()) {
            String aggName = name.getKey().toString();

            Map<String,Object> valueMap = (Map<String, Object>) name.getValue();
            for (Map.Entry value : valueMap.entrySet()) {
                String aggType = value.getKey().toString();
                Map<String,Object> fieldMap = (Map<String, Object>) value.getValue();
                aggregationBuilder = setAggsBuilders(aggName,aggType,fieldMap);
                if("terms".equals(aggType)){
                    Map<String,Object> innerAggsMap = (Map<String, Object>) valueMap.get("aggs");
                    if(MapUtils.isNotEmpty(innerAggsMap)){
                        joinSecEsStrAggs(innerAggsMap, aggregationBuilder);
                    }
                }
                if(aggregationBuilder != null){
                    searchSourceBuilder.aggregation(aggregationBuilder);
                }
            }
        }

    }


    /**
     *  字符型的拼接
     * 第二层用 aggregationBuilder 的 subAggregation 方法添加后面的内容
     */
    private static void joinSecEsStrAggs(Map<String,Object> aggsNameMap, AggregationBuilder allAggregationBuilder) {

        AggregationBuilder aggregationBuilder;
        for (Map.Entry name : aggsNameMap.entrySet()) {
            String aggName = name.getKey().toString();

            Map<String,Object> valueMap = (Map<String, Object>) name.getValue();
            for (Map.Entry value : valueMap.entrySet()) {
                String aggType = value.getKey().toString();
                Map<String,Object> fieldMap = (Map<String, Object>) value.getValue();
                aggregationBuilder = setAggsBuilders(aggName,aggType,fieldMap);
                if("terms".equals(aggType)){
                    Map<String,Object> innerAggsMap = (Map<String, Object>) valueMap.get("aggs");
                    if(MapUtils.isNotEmpty(innerAggsMap)){
                        joinSecEsStrAggs(innerAggsMap, aggregationBuilder);
                    }
                }
                if("bucket_script".equals(aggType)){
                    BucketScriptPipelineAggregationBuilder bucketScript = getBucketScript(aggName,fieldMap);
                    if(aggregationBuilder != null){
                        aggregationBuilder.subAggregation(bucketScript);
                    }else{
                        allAggregationBuilder.subAggregation(bucketScript);
                    }
                }
                if(aggregationBuilder != null){
                    allAggregationBuilder.subAggregation(aggregationBuilder);
                }

            }

        }


    }

    private static BucketScriptPipelineAggregationBuilder getBucketScript(String aggName, Map<String, Object> aggParam){
        // 这边还得把之前的添加到一块
        Map<String, String> bucketsPathHashMap = (Map<String, String>) aggParam.get("buckets_path");
        return PipelineAggregatorBuilders.bucketScript(aggName, bucketsPathHashMap,
                new Script(MapUtils.getString(aggParam,"script"))).format("#.##");
    }

    /**
     *  根据聚合类型 获取对应的聚合builder
     * @param aggName  聚合名称
     * @param aggType  聚合类型
     * @param aggParam  聚合参数
     * @return AggregationBuilder
     */
    private static AggregationBuilder setAggsBuilders(String aggName, String aggType,  Map<String, Object> aggParam){

        String fieldValue = MapUtils.getString(aggParam, "field");

        AggregationBuilder aggregationBuilder = null;
        if("terms".equals(aggType)){
            int size = MapUtils.getIntValue(aggParam, "size");
            if(size == NumberUtils.INTEGER_ZERO){
                size = 10;
            }
            aggregationBuilder = AggregationBuilders.terms(aggName).field(fieldValue).size(size);
        }else if("sum".equals(aggType)){
            aggregationBuilder = AggregationBuilders.sum(aggName).field(fieldValue);
        }else if("avg".equals(aggType)){
            aggregationBuilder = AggregationBuilders.avg(aggName).field(fieldValue);
        }else if("max".equals(aggType)){
            aggregationBuilder = AggregationBuilders.max(aggName).field(fieldValue);
        }else if("min".equals(aggType)){
            aggregationBuilder = AggregationBuilders.min(aggName).field(fieldValue);
        }else if("value_count".equals(aggType)){
            aggregationBuilder = AggregationBuilders.count(aggName).field(fieldValue);
        }else if ("cardinality".equals(aggType)) {// 去重之后总数
            aggregationBuilder = AggregationBuilders.cardinality(aggName).field(fieldValue);
        } else if ("histogram".equals(aggType)) {// 直方图
            Double interval = MapUtils.getDouble(aggParam, "interval");
            Long minDocCount = MapUtils.getLong(aggParam, "min_doc_count");
            aggregationBuilder = AggregationBuilders.histogram(aggName).field(fieldValue).interval(interval)
                    .minDocCount(minDocCount);
        } else if ("date_histogram".equals(aggType)) {// 日期直方图
            String interval = MapUtils.getString(aggParam, "interval");
            String format = MapUtils.getString(aggParam, "format");
            Long minDocCount = MapUtils.getLong(aggParam, "min_doc_count");
            DateHistogramAggregationBuilder dateHistogramAggregationBuilder = AggregationBuilders.dateHistogram(aggName)
                    .field(fieldValue).dateHistogramInterval(new DateHistogramInterval(interval))
                    .minDocCount(minDocCount).timeZone(DateTimeZone.forOffsetHours(8));
            if (StringUtils.isNotEmpty(format)) {
                dateHistogramAggregationBuilder.format(format);
            }
            aggregationBuilder = dateHistogramAggregationBuilder;
        } else if ("range".equals(aggType)) {// 范围
            String fieleName = MapUtils.getString(aggParam, "field");
            List<Map<String, Object>> ranges = (List<Map<String, Object>>) aggParam.get("ranges");
            RangeAggregationBuilder rangeAggregationBuilder = AggregationBuilders.range(aggName).field(fieleName);
            ListUtils.emptyIfNull(ranges).forEach(e -> {
                Double from = MapUtils.getDouble(e, "from");
                Double to = MapUtils.getDouble(e, "to");
                rangeAggregationBuilder.addRange(from, to);
            });

            aggregationBuilder = rangeAggregationBuilder;
        } else if ("date_range".equals(aggType)) {// 日期范围
            String fieleName = MapUtils.getString(aggParam, "field");
            String format = MapUtils.getString(aggParam, "format");
            List<Map<String, Object>> ranges = (List<Map<String, Object>>) aggParam.get("ranges");
            DateRangeAggregationBuilder dateRangeAggregationBuilder = AggregationBuilders.dateRange(aggName)
                    .field(fieleName).timeZone(DateTimeZone.forOffsetHours(8));

            if (StringUtils.isNotEmpty(format)) {
                dateRangeAggregationBuilder.format(format);
            }
            ListUtils.emptyIfNull(ranges).forEach(e -> {
                String from = MapUtils.getString(e, "from");
                String to = MapUtils.getString(e, "to");
                dateRangeAggregationBuilder.addRange(from, to);
            });
            aggregationBuilder = dateRangeAggregationBuilder;
        }
        return aggregationBuilder;
    }

}

参数处理的部分,再贴出来

2,查询聚合getEsAggs

public void getEsAggs(EsQuery esQuery) {
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    SearchRequest searchRequest = new SearchRequest();
    // 查询的索引
    searchRequest.indices(esQuery.getSourceIndex());
  
    String sourceExpr = esQuery.getSourceExpr();
    String queryStr = "";
    JSONObject searchJson = JSONObject.parseObject(sourceExpr);
    // 参数,带query 和 aggs的, 只有aggs的
    WrapperQueryBuilder wrapperQueryBuilder = null;

    if (!StringUtils.isEmpty(sourceExpr)) {
        // 查询参数
        if (sourceExpr.contains("query")) {// 带有query的查询
            queryStr = searchJson.getJSONObject("query").toJSONString();
        }
        if (StringUtils.isNotEmpty(queryStr)) {
            wrapperQueryBuilder = QueryBuilders.wrapperQuery(queryStr);
        }

        // 聚合参数
        JSONObject aggs = searchJson.getJSONObject("aggregations");
        StrTermNextScript.joinEsStrAggs(aggs, searchSourceBuilder);
    }

    if (wrapperQueryBuilder != null) {
        searchSourceBuilder.query(wrapperQueryBuilder);
    }
    searchSourceBuilder.size(0);
    searchRequest.source(searchSourceBuilder);
    System.out.println("aggExpr " + searchSourceBuilder.toString());

    try {
        SearchResponse searchResponse = highLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        logger.info(searchResponse.toString());
        Aggregations aggregations = searchResponse.getAggregations();
        List<Aggregation> aggregationList = aggregations.asList();

        for (Aggregation aggregation : aggregationList) {
            logger.info(JSON.toJSONString(aggregation));
            Terms histogram = (Terms) aggregation;
            for (Terms.Bucket bucket : histogram.getBuckets()) {
                logger.info(bucket.getKeyAsString());
                logger.info("" + bucket.getDocCount());
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

聚合查询的时候,size设置为0

总结:

    Es聚合参数,包括参数部分和聚合部分。参数部分只用处理参数部分,分页,排序,那些就不用处理了。聚合部分,参数处理好了,就是获取值了。对于值的处理,又是需要花点时间处理。

下一篇: 《平铺es聚合数据》

Java代码中使用ElasticsearchES)进行分组聚合,通常是通过ElasticsearchJava客户端库来实现的。这通常涉及以下步骤: 1. **添加依赖**:首先,需要在项目中添加Elasticsearch的客户端库依赖,比如使用Spring Data Elasticsearch或直接使用Elasticsearch官方的RestHighLevelClient。 2. **创建客户端连接**:使用`RestHighLevelClient`类创建与ES集群的连接。 3. **构建查询**:构建一个聚合查询,例如使用`TermsAggregationBuilder`来实现分组(group by)。 4. **执行查询**:将构建好的查询通过客户端发送给Elasticsearch集群执行。 5. **处理结果**:从返回的结果中提取并处理所需的聚合数据。 下面是一个使用`RestHighLevelClient`的简单示例代码,展示如何在Java中执行一个按照某个字段分组的聚合查询: ```java 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.index.query.QueryBuilders; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import org.elasticsearch.search.builder.SearchSourceBuilder; // 创建RestHighLevelClient实例 RestHighLevelClient client = new RestHighLevelClient( RestClient.builder(new HttpHost("localhost", 9200, "http"))); try { // 创建一个分组聚合查询 TermsAggregationBuilder aggregation = AggregationBuilders.terms("group_by_field").field("field_name"); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.aggregation(aggregation); searchSourceBuilder.query(QueryBuilders.matchAllQuery()); // 创建搜索请求 SearchRequest searchRequest = new SearchRequest("index_name"); searchRequest.source(searchSourceBuilder); // 执行搜索请求 SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); // 处理响应 Aggregations aggregations = searchResponse.getAggregations(); Terms groupByField = aggregations.get("group_by_field"); for (Terms.Bucket bucket : groupByField.getBuckets()) { String key = bucket.getKeyAsString(); // 处理每个分组的数据 } } catch (IOException e) { e.printStackTrace(); } finally { // 关闭客户端连接 try { client.close(); } catch (IOException e) { e.printStackTrace(); } } ``` 在上面的代码中,我们创建了一个`TermsAggregationBuilder`实例来对名为`field_name`的字段进行分组聚合,并通过`searchRequest`发送查询请求Elasticsearch的`index_name`索引。然后处理返回的结果,提取每个分组的键(key)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天狼1222

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值