需求
有三个字段 需要把A字段和B字段结合起来 共同分组
用Mysql 写的话 就相当一是 Select A,B from 表名 group by A,B
但是在elasticsearch 的查询中分组都是 :
Aggregation(中文意思:聚合)关键字进行聚合分组,然后是最关键的,多个group by不能使用并列Aggregation,必须使用嵌套聚合,采用subAggregation进行嵌套!!
TermsAggregationBuilder agg_top_elapsed_time_by_application =
AggregationBuilders.terms("xxxxxxxxx").field("你在ES 的字段名字")
.subAggregation(AggregationBuilders.sum("xxxxxx").field("你在ES 的字段名字"));
在Java Api 里面只能这样嵌套查询不能说把这两个分组并列 在kibana 的语法中是可以使用脚本去把我们想要的group by 给结果 如下
GET /{索引名}/_search
{
"size": 0,
"query": {
"match_all": {}
},
"aggs": {
"sexprof": {
"terms": {
"script": {
"inline": "doc['destination_port'].value +'-split-'+ doc['protocol_id'].value"
}
}
}
}
}
结果 接下来就是调用Java Api 来查询了 网上说要更改YML 配置的都是假的最后是查看官方给的Api 才发现官方早就停止使用groovy 所以用的painless 代码如下
Script script = new Script(ScriptType.INLINE,"painless", "doc['A'].value+'-'+doc['B'].value",new HashMap<String, Object>());
AggregationBuilder aggregationBuilderCount = AggregationBuilders.terms("定义名字").script(script).order(BucketOrder.count(false)).size(3).subAggregation(protocolIDTerm);
结果如下 整体代码
String indexName = "xxxxxx";
SearchRequest searchRequest = new SearchRequest(indexName);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.size(0);
Script script = new Script(ScriptType.INLINE,"painless", "doc['A'].value+'-'+doc['B'].value",new HashMap<String, Object>());
AggregationBuilder aggregationBuilderCount = AggregationBuilders.terms("你定义名字").script(script).order(BucketOrder.count(false)).size(3).subAggregation(protocolIDTerm);
searchSourceBuilder.aggregation(aggregationBuilderCount);
searchRequest.source(searchSourceBuilder);
SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
Aggregations aggregations = response.getAggregations();
Terms aggregation = aggregations.get("你定义名字");
List<? extends Terms.Bucket> list = aggregation.getBuckets();
list.stream().forEach(prot -> {
System.out.println("======= 端口 " + prot.getKey() + ":" + prot.getDocCount() + "==============");
});
|