聚合案例。
ES中可以实现基于字段进行分组聚合的统计,聚合操作支持count()、sum()、avg()、max()、min()等聚会函数。
下面来看两个案例:
1).统计相同年龄的学员个数
package com.simoniu.db_elasticsearch.aggregations;
import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import java.util.List;
/**
* 聚合统计:统计相同年龄的学员个数
* Created by simoniu
*/
public class EsAggCaseDemo1 {
public static void main(String[] args) throws Exception{
//获取RestClient连接
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("master", 9200, "http"),
new HttpHost("slave1", 9200, "http"),
new HttpHost("slave2", 9200, "http")));
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("myschool");
//指定查询条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//指定分组信息,默认是执行count聚合
TermsAggregationBuilder aggregation = AggregationBuilders.terms("age_term")
.field("age");
//aggregation.size(Integer.MAX_VALUE);//获得所有分组,默认返回是10个
searchSourceBuilder.aggregation(aggregation);
searchRequest.source(searchSourceBuilder);
//执行查询操作
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//获取分组信息
Terms terms = searchResponse.getAggregations().get("age_term");
List<? extends Terms.Bucket> buckets = terms.getBuckets();
for (Terms.Bucket bucket: buckets) {
System.out.println(bucket.getKey()+"---"+bucket.getDocCount());
}
//关闭连接
client.close();
}
}
运行结果:
19---4
17---2
12---1
15---1
16---1
20---1
21---1
22---1
23---1
28---1
2).统计每个学员的总成绩
初始化score索引数据如下:
curl -H "Content-Type: application/json" -XPOST 'http://master:9200/score/_doc/1' -d'{"name":"张三","subject":"chinese","score":59}'
curl -H "Content-Type: application/json" -XPOST 'http://master:9200/score/_doc/6' -d'{"name":"王五","subject":"math","score":68}'
curl -H "Content-Type: application/json" -XPOST 'http://master:9200/score/_doc/3' -d'{"name":"李四","subject":"chinese","score":78}'
curl -H "Content-Type: application/json" -XPOST 'http://master:9200/score/_doc/2' -d'{"name":"张三","subject":"math","score":89}'
curl -H "Content-Type: application/json" -XPOST 'http://master:9200/score/_doc/4' -d'{"name":"李四","subject":"math","score":85}'
curl -H "Content-Type: application/json" -XPOST 'http://master:9200/score/_doc/5' -d'{"name":"王五","subject":"chinese","score":97}'
java代码实现:
package com.simoniu.db_elasticsearch.aggregations;
import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.Sum;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import java.util.List;
/**
* 聚合统计:统计每个学员的总成绩
* Created by simoniu
*/
public class EsAggCaseDemo2 {
public static void main(String[] args) throws Exception{
//获取RestClient连接
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("master", 9200, "http"),
new HttpHost("slave1", 9200, "http"),
new HttpHost("slave2", 9200, "http")));
SearchRequest searchRequest = new SearchRequest();
searchRequest.indices("score");
//指定查询条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//指定分组和求sum
TermsAggregationBuilder aggregation = AggregationBuilders.terms("name_term")
.field("name.keyword")//指定分组字段,如果是字符串(Text)类型,则需要指定使用keyword类型
.subAggregation(AggregationBuilders.sum("sum_score").field("score"));//指定求sum,也支持avg、min、max等操作
searchSourceBuilder.aggregation(aggregation);
searchRequest.source(searchSourceBuilder);
//执行查询操作
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//获取分组信息
Terms terms = searchResponse.getAggregations().get("name_term");
List<? extends Terms.Bucket> buckets = terms.getBuckets();
for (Terms.Bucket bucket: buckets) {
//获取sum聚合的结果
Sum sum = bucket.getAggregations().get("sum_score");
System.out.println(bucket.getKey()+"---"+sum.getValue());
}
//关闭连接
client.close();
}
}
运行结果:
张三---148.0
李四---163.0
王五---165.0