以前寫過《es~經過ElasticsearchTemplate進行聚合操做》的文章,這一次主要寫一個嵌套的聚合,例如先對sex集合,再對desc聚合,最後再對age求和,共三層嵌套。
Aggregations的部分特性相似於SQL語言中的group by,avg,sum等函數,Aggregations須要理解兩個概念:html
// 建立一個查詢條件對象 BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); // 拼接查詢條件 queryBuilder.should(QueryBuilders.termQuery("creator", "1")); // 建立聚合查詢條件 TermsAggregationBuilder sexAgg = AggregationBuilders .terms("sex") .field("sex.keyword");//keyword表示不使用分詞進行聚合,全字匹配 TermsAggregationBuilder descAgg = AggregationBuilders .terms("desc") .field("desc.keyword");//keyword表示不使用分詞進行聚合,全字匹配 SumAggregationBuilder ageSumAgg = AggregationBuilders .sum("ageSum") .field("age"); //嵌套 descAgg.subAggregation(ageSumAgg); sexAgg.subAggregation(descAgg); // 建立查詢對象 SearchQuery build = new NativeSearchQueryBuilder() .withQuery(queryBuilder) //添加查詢條件 .addAggregation(sexAgg) // 添加聚合條件 .withPageable(PageRequest.of(0, 1)) //符合查詢條件的文檔分頁,若是文檔比較大,能夠把這個分頁改小(不是聚合的分頁) .build(); // 執行查詢 AggregatedPage<TestEsDto> testEntities = elasticsearchTemplate.queryForPage(build, TestEsDto.class); // 取出聚合結果 Aggregations entitiesAggregations = testEntities.getAggregations(); Terms terms = (Terms) entitiesAggregations.asMap().get("sex"); // 遍歷取出聚合字段列的值,與對應的數量 for (Terms.Bucket bucket : terms.getBuckets()) { Terms descTerms = (Terms) bucket.getAggregations().asMap().get("desc"); for (Terms.Bucket descTermsBucket : descTerms.getBuckets()) { ParsedSum parsedSum = descTermsBucket.getAggregations().get("ageSum");//注意從bucket而不是searchResponse System.out.println(bucket.getKeyAsString() + "\t" + bucket.getDocCount() + "\t" + descTermsBucket.getKeyAsString() + "\t" + parsedSum.getValueAsString()); } }
結果
elasticsearch