Elasticsearch Aggregation 多个字段分组统计 Java API实现
现有索引数据:
index:school
type:student
---------------------------------------------------
{"grade":"1", "class":"1", "name":"xiao 1"}
{"grade":"1", "class":"1", "name":"xiao 2"}
{"grade":"1", "class":"2", "name":"xiao 3"}
{"grade":"1", "class":"2", "name":"xiao 4"}
{"grade":"1", "class":"2", "name":"xiao 5"}
Java分组统计年级和班级学生个数,如SQL: SELECT grade,class,count(1) FROM student GROUP BY grade,class;
1 package test; 2 3 import java.util.Iterator; 4 import java.util.Map; 5 6 import org.elasticsearch.action.search.SearchRequestBuilder; 7 import org.elasticsearch.action.search.SearchResponse; 8 import org.elasticsearch.action.search.SearchType; 9 import org.elasticsearch.search.aggregations.Aggregation; 10 import org.elasticsearch.search.aggregations.AggregationBuilders; 11 import org.elasticsearch.search.aggregations.bucket.terms.StringTerms; 12 import org.elasticsearch.search.aggregations.bucket.terms.Terms.Bucket; 13 import org.elasticsearch.search.aggregations.bucket.terms.TermsBuilder; 14 import org.junit.Test; 15 16 import utils.NesUtils; 17 18 public class TestAggregation 19 { 20 @Test 21 public void testAggregation() 22 { 23 SearchRequestBuilder srb = NesUtils.getSearcher("school"); 24 srb.setTypes("student"); 25 srb.setSearchType(SearchType.COUNT); 26 27 TermsBuilder gradeTermsBuilder = AggregationBuilders.terms("gradeAgg").field("grade"); 28 TermsBuilder classTermsBuilder = AggregationBuilders.terms("classAgg").field("class"); 29 30 gradeTermsBuilder.subAggregation(classTermsBuilder); 31 32 srb.addAggregation(gradeTermsBuilder); 33 34 SearchResponse sr = srb.execute().actionGet(); 35 36 Map<String, Aggregation> aggMap = sr.getAggregations().asMap(); 37 38 StringTerms gradeTerms = (StringTerms) aggMap.get("gradeAgg"); 39 40 Iterator<Bucket> gradeBucketIt = gradeTerms.getBuckets().iterator(); 41 42 while(gradeBucketIt.hasNext()) 43 { 44 Bucket gradeBucket = gradeBucketIt.next(); 45 System.out.println(gradeBucket.getKey() + "年级有" + gradeBucket.getDocCount() +"个学生。"); 46 47 StringTerms classTerms = (StringTerms) gradeBucket.getAggregations().asMap().get("classAgg"); 48 Iterator<Bucket> classBucketIt = classTerms.getBuckets().iterator(); 49 50 while(classBucketIt.hasNext()) 51 { 52 Bucket classBucket = classBucketIt.next(); 53 System.out.println(gradeBucket.getKey() + "年级" +classBucket.getKey() + "班有" + classBucket.getDocCount() +"个学生。"); 54 } 55 System.out.println(); 56 } 57 58 } 59 }
运行完成输出结果
---------------------------------------------------
1年级有5个学生。
1年级2班有3个学生。
1年级1班有2个学生。