原创Java使用RestHighLevelClient操作ElasticSearch,实现多字段Group by并将结果进行count排序
Posted DCTANT
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了原创Java使用RestHighLevelClient操作ElasticSearch,实现多字段Group by并将结果进行count排序相关的知识,希望对你有一定的参考价值。
前言
之前写过一篇使用RestHighLevelClient进行多字段group by的(【原创】ElasticSearch使用Java代码group by多个字段查询统计数量_DCTANT的博客-CSDN博客_elasticsearch分组统计 java),其实那篇并不完美,最佳的group by方法应该用script,而不是像之前那篇博客一样去递归求和,虽然也不是不行,但是这个毕竟太暴力了,效率也不高。
直接上代码:
初始化RestHighLevelClient我这边为了节省篇幅先跳过了,直接上核心:
SearchRequest searchRequest = new SearchRequest(index);
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//为了保持顺序,使用LinkedHashMap,防止进入map后变成乱序排列
LinkedHashMap<String, Long> nameCountMap = new LinkedHashMap<>();
//group by后再order by
BucketOrder bucketOrder = BucketOrder.count(false); //这里的count方法中true表示升序排列,false代表降序排列
AggregationBuilder aggregationBuilder = AggregationBuilders.terms("$分组名") //分组名可以随便填,但是必须和后面aggregations.get("$分组名");里面填的分组名保持一致,否则会返回null,导致后续空指针异常
.script(new Script("doc['$字段1'].value+'@@'+doc['$字段2'].value+'@@'+doc['$字段3'].value+'@@'+doc['$字段4'].value")) //相当于group by 4个字段,其中的@@是字段间的分隔符,最后ES返回的结果是这样的$字段1@@$字段2@@$字段3@@$字段4
.size(20) //聚合返回20个值(不传默认返回10个值)
.order(bucketOrder); //将上方的排序填入,让ES进行排序
sourceBuilder.aggregation(aggregationBuilder); //填入分组信息
searchRequest.source(sourceBuilder);
try
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
Aggregations aggregations = searchResponse.getAggregations();
Terms terms = aggregations.get("$分组名"); //填入上方terms()中相同的分组名
for (Terms.Bucket bucket : terms.getBuckets())
String key = bucket.getKeyAsString(); //这里的key值是这样的:$字段1@@$字段2@@$字段3@@$字段4
long count = bucket.getDocCount(); //group by后聚合统计出来的数量
String[] split = key.split("@@"); //切开作为分隔符的@@,取里面需要的字段放入nameCountMap就行了
nameCountMap.put(split[0], count); //假设取第0个字段作为key
catch (IOException e)
e.printStackTrace();
// todo 处理剩下的业务逻辑
看一下注释应该就能懂了,相当于ES的查询为:
"aggs":
"myStatistic":
"terms":
"script":
"inline":"doc['字段1'].value+'@@'+doc['字段2'].value+'@@'+doc['字段3'].value+'@@'+doc['字段4'].value"
,
"size":20,
"order":
"_count":"desc"
参考链接:Elasticsearch入门 ,使用 script 做聚合查询 - 简书
如果script中的字段,其中有个值不存在则会报这个错:
解决方案如这个博客所示,我这边不再赘述
以上是关于原创Java使用RestHighLevelClient操作ElasticSearch,实现多字段Group by并将结果进行count排序的主要内容,如果未能解决你的问题,请参考以下文章
[原创]java WEB学习笔记36:Java Bean 概述,及在JSP 中的使用,原理
原创Java使用RestHighLevelClient操作ElasticSearch,实现多字段Group by并将结果进行count排序
原创Java使用RestHighLevelClient操作ElasticSearch,实现多字段Group by并将结果进行count排序