The book continues, the
previous article wrote that elasticsearch sorted the aggregated results
This article is about filtering the scope after aggregation.
In general, we can use range in query or filter to perform range filtering, but how do we filter the aggregated results in the aggregation to match the range of aggregation results?
The dsl statement is as follows:
"aggregations": {
"statistics_assets": {
"terms": {
"field": "one_account.one_account_no",
"size": 10
},
"aggregations": {
"assets": {
"sum": {
"field": "assets.merge"
}
},
"assets_sum_range": {
"bucket_selector": {
"buckets_path": {
"key": "assets"
},
"script": {
"source": "0<=params.key&¶ms.key<=100000",
"lang": "painless"
}
}
}
}
}
}
Use bucket_selector in assets_sum_range to filter the result of "assets.merge" after sum aggregation. The filter condition range is 0<=aggregation result<=100000
Java code:
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("statistics_assets")
.field("one_account.one_account_no")
.size(10);
AggregationBuilder assetsAggregation = AggregationBuilders.sum("assets").field("assets.merge");
termsAggregationBuilder.subAggregation(assetsAggregation);
//对聚合后的总资产进行范围选择
Map<String, String> bucketsPathsMap = new HashMap<>();
bucketsPathsMap.put("key", "assets");
Script script = new Script( "0<=params.key&¶ms.key<=100000" );
BucketSelectorPipelineAggregationBuilder bs = PipelineAggregatorBuilders.bucketSelector("assets_sum_range", bucketsPathsMap, script);
termsAggregationBuilder.subAggregation(bs);
searchSourceBuilder.aggregation(termsAggregationBuilder);
The final output is the aggregation result in the range of 0-100000:
"aggregations" : {
"statistics_assets" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 4,
"buckets" : [
{
"key" : "110600000973",
"doc_count" : 2,
"assets" : {
"value" : 0.0
}
},
{
"key" : "105100015207",
"doc_count" : 1,
"assets" : {
"value" : 9.999
}
}
]
}
}