ElasticSearch 之 BucketScriptPipelineAggregationBuilder 代码实现

本文介绍如何使用Elasticsearch的Bucket Script Aggregation进行分组并计算特定字段的比率及总和,通过Java代码和DSL查询实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

官网链接:

Bucket Script Aggregation | Elasticsearch Guide [6.4] | Elastic

实现功能:

select sum(col01),sum(col02),sum(col03)。。。,sum(col01)/sum(col02) from log  group by col5

Java代码实现分组求比值,求和:

    public void searchAgg(String indexName,String typeName, String query, String groupByFieldName,String sumCols1,String sumCols2) {
        try {
            TermsAggregationBuilder aggBuilder = AggregationBuilders.terms(ELASTIC_SEARCH__AGGREGATION_NAME).field(groupByFieldName).size(10);

            SumAggregationBuilder subSumAgg1 = AggregationBuilders.sum(sumCols1 + ELASTIC_SEARCH__SUB_AGGREGATION_NAME__TAIL).field(sumCols1);
            aggBuilder.subAggregation(subSumAgg1);

            SumAggregationBuilder subSumAgg2 = AggregationBuilders.sum(sumCols2 + ELASTIC_SEARCH__SUB_AGGREGATION_NAME__TAIL).field(sumCols2);
            aggBuilder.subAggregation(subSumAgg2);

            HashMap<String, String> bucketPathMaps = new HashMap<>();

            String bucketPath01=sumCols1+"_sum";
            String bucketPath02=sumCols2+"_sum";

            bucketPathMaps.put(bucketPath01,sumCols1 + ELASTIC_SEARCH__SUB_AGGREGATION_NAME__TAIL);
            bucketPathMaps.put(bucketPath02,sumCols2 + ELASTIC_SEARCH__SUB_AGGREGATION_NAME__TAIL);

            String script="params."+bucketPath01+"/params."+bucketPath02;
            Script inline = new Script(script);

            BucketScriptPipelineAggregationBuilder divisionAgg = new BucketScriptPipelineAggregationBuilder("division", bucketPathMaps, inline);
            aggBuilder.subAggregation(divisionAgg);
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            sourceBuilder.query(QueryBuilders.queryStringQuery(query));
            sourceBuilder.aggregation(aggBuilder);

            //构建查询请求,封装请求体
            SearchRequest searchRequest = new SearchRequest(indexName.split(",")).types(typeName);
            searchRequest.source(sourceBuilder);
            //处理返回的请求
            SearchResponse searchResponse = mClient.search(searchRequest, RequestOptions.DEFAULT);
            Terms terms = searchResponse.getAggregations().get(ELASTIC_SEARCH__AGGREGATION_NAME);
            Iterator<? extends Terms.Bucket> iterator = terms.getBuckets().iterator();

            while (iterator.hasNext()) {
                Terms.Bucket bucket = iterator.next();
                Map<String, Aggregation> subAggMap = bucket.getAggregations().asMap();
                Set<String> strings = subAggMap.keySet();
                for (String key:strings) {
                    Aggregation aggregation = subAggMap.get(key);
                    if(aggregation instanceof Sum){
                    double value = ((Sum) subAggMap.get(key)).getValue();
                        System.out.println("sum 分子和分母:"+value);
                    }else{
                        double value = ((ParsedSimpleValue) subAggMap.get(key)).value();
                        System.out.println("比值:"+value);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

上述代码对应的dsl实现:

curl -XGET http://localhost:9200/test/_search?pretty -H 'Content-Type:application/json' --data-binary '
{
    "query":{
        "query_string":{
            "query":"id:cafba57439eb40f1827670ac5dcf37ab"
        }
    },
    "aggregations":{
        "group_by_state":{
            "terms":{
                "field":"lastGroupId"
            },
            "aggregations":{
                "sessionDuration_Agg":{
                    "sum":{
                        "field":"duration"
                    }
                },
                "sessionHumanValid_Agg":{
                    "sum":{
                        "field":"validFlag"
                    }
                },
                "division":{
                    "bucket_script":{
                        "buckets_path":{
                            "sessionDuration_sum":"sessionDuration_Agg",
                            "sessionHumanValid_sum":"sessionHumanValid_Agg"
                        },
                        "script":{
                            "source":"params.sessionDuration_sum/params.sessionHumanValid_sum",
                            "lang":"painless"
                        },
                        "gap_policy":"skip"
                    }
                }
            }
        }
    }
}
'

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值