ES的聚合主要有Bucket、Metric、Pipeline Aggregations ,本篇主要介紹Bucket、Metric這兩種。
聚合:從數(shù)據(jù)中分組和提取數(shù)據(jù)。類似于 SQL GROUP BY 和 SQL 聚合函數(shù)
聚合語法:
"aggregations" : {
"<聚合名稱 1>" : {
"<聚合類型>" : {
<聚合體內(nèi)容>
}
[,"元數(shù)據(jù)" : { [<meta_data_body>] }]?
[,"aggregations" : { [<sub_aggregation>]+ }]?
}
[,"聚合名稱 2>" : { ... }]*
}
實(shí)例數(shù)據(jù)
Elasticsearch 示例數(shù)據(jù) accounts.json 下載
kibana中執(zhí)行
POST /bank/account/_bulk
示例 1:搜索 address 中包含 Lane的所有人的年齡分布 ( 前 10 條 ) 以及平均年齡,以及平均薪資
DSL語句
GET bank/_search
{
"size": 0,
"query": {
"match": {
"address": "Lane"
}
},
"aggs": {
"ageAggs": {
"terms": {
"field": "age",
"size": 10
}
},
"avgAge": {
"avg": {
"field": "age"
}
},
"avgPrice": {
"avg": {
"field": "balance"
}
}
}
}
java代碼
public void testSearchData() throws IOException {
SearchRequest request = new SearchRequest();
request.indices("bank");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 1.1)address 中包含 road 的所有人
sourceBuilder.query(QueryBuilders.matchQuery("address", "road"));
// 1.2)按照年齡分布進(jìn)行聚合
TermsAggregationBuilder ageAgg = AggregationBuilders.terms("ageAgg").field("age").size(10);
sourceBuilder.aggregation(ageAgg);
// 1.3)計(jì)算平均薪資
AvgAggregationBuilder balanceAvg = AggregationBuilders.avg("balanceAvg").field("balance");
sourceBuilder.aggregation((balanceAvg));
System.out.println("檢索參數(shù):" + sourceBuilder.toString());
request.source(sourceBuilder);
// 2、執(zhí)行檢索
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 3、分析結(jié)果
System.out.println(response.toString());
// 3.1)獲取查到的數(shù)據(jù)。
SearchHits hits = response.getHits();
// 3.2)獲取真正命中的結(jié)果
SearchHit[] searchHits = hits.getHits();
// 3.3)遍歷命中結(jié)果
for (SearchHit hit : searchHits) {
String hitStr = hit.getSourceAsString();
BankMember bankMember = JSON.parseObject(hitStr, BankMember.class);
System.out.println(bankMember);
}
// 3.4)獲取聚合信息
// 參考文檔:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-search.html
Aggregations aggregations = response.getAggregations();
Terms ageAgg1 = aggregations.get("ageAgg");
for (Terms.Bucket bucket : ageAgg1.getBuckets()) {
String keyAsString = bucket.getKeyAsString();
System.out.println("用戶年齡: " + keyAsString + " 人數(shù):" + bucket.getDocCount());
}
Avg balanceAvg1 = aggregations.get("balanceAvg");
System.out.println("平均薪資:" + balanceAvg1.getValue());
}

kibana查詢結(jié)果

java執(zhí)行結(jié)果
示例 2:按照年齡分組,然后將分組后的結(jié)果按照性別分組,然后查詢出這些分組后的平均薪資
DSL語句
GET bank/_search
{
"size": 0,
"query": {
"match_all": {}
},
"aggs": {
"ageAggs": {
"terms": {
"field": "age",
"size": 10
},
"aggs": {
"genderAgg": {
"terms": {
"field": "gender.keyword",
"size": 10
},
"aggs": {
"avgBalance": {
"avg": {
"field": "balance"
}
}
}
}
}
}
}
}
java代碼
@Test
public void testAgeAggs2() throws IOException {
SearchRequest request = new SearchRequest("bank");
SearchSourceBuilder searchSourceBuilder = request.source();
TermsAggregationBuilder ageAgg = AggregationBuilders.terms("ageAgg").field("age").size(10);
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
ageAgg.subAggregation(AggregationBuilders.terms("genderAgg")
.field("gender.keyword")
.subAggregation(AggregationBuilders.avg("balanceAvg")
.field("balance"))
);
searchSourceBuilder.aggregation(ageAgg);
request.source(searchSourceBuilder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
Aggregations aggregations = response.getAggregations();
//拿到桶
Terms ageAgg1 = aggregations.get("ageAgg");
//最外層年齡桶
for (Terms.Bucket bucket : ageAgg1.getBuckets()) {
String ageString = bucket.getKeyAsString();
long ageDocCount = bucket.getDocCount();
Aggregations genderAggregations = bucket.getAggregations();
//年齡桶
Terms genderTerm = genderAggregations.get("genderAgg");
for (Terms.Bucket genderTermbucket : genderTerm.getBuckets()) {
String genderString = genderTermbucket.getKeyAsString();
long genderdocCount = genderTermbucket.getDocCount();
//年齡指標(biāo)
Avg balanceAvg = genderTermbucket.getAggregations().get("balanceAvg");
System.out.println("用戶年齡: " + ageString + " 人數(shù):" + ageDocCount + "用戶性別: " + genderString + " 人數(shù):" + genderdocCount+ "平均薪資:" + balanceAvg.getValue());
}
}
}

kibana查詢視圖

java查詢結(jié)果