es~經過ElasticsearchTemplate進行聚合~Nested嵌套聚合

Nested是一種嵌套文檔,相似於父子文檔,它能夠將與主文檔有關的數據進行存儲,能夠把它理解成一張子表,它的查詢和聚合性能很好;更新性能通常。數據結構

下面是測試使用的數據結構,一個包含Nested屬性的實體

@Document(indexName = "esdto", type = "esdto")
@Data
@ToString(callSuper = true)
@AllArgsConstructor
@NoArgsConstructor
public class TestEsDto extends EsBaseEntity implements Serializable {


    @Field(type = FieldType.Keyword)
    private String name;
    private Integer age;
    @Field(type = FieldType.Keyword)
    private String sex;
    @Field(type = FieldType.Keyword)
    private String desc;
    @Field(type = FieldType.Nested)
    private List<Person> personList;


    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @ToString
    public static class Person {
        private Integer age;
        @Field(type = FieldType.Keyword)
        private String sex;
        @Field(type = FieldType.Keyword)
        private String desc;
    }
}

存儲的數據如圖

0

聚合代碼

// 建立一個查詢條件對象
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        // 拼接查詢條件
        queryBuilder.should(QueryBuilders.termQuery("creator", "1"));

        // 嵌套聚合
        AbstractAggregationBuilder aggregation =
                AggregationBuilders
                    .nested("personList", "personList")
                    .subAggregation(AggregationBuilders
                        .terms("sex").field("personList.sex")
                        .subAggregation(
                            AggregationBuilders
                                .terms("desc").field("personList.desc")
                                .subAggregation(
                                    AggregationBuilders
                                            .sum("ageSum").field("personList.age")
                                )
                        )
                    );


        // 建立查詢對象
        SearchQuery build = new NativeSearchQueryBuilder()
                .withQuery(queryBuilder) //添加查詢條件
                .addAggregation(aggregation) // 添加聚合條件
                .withPageable(PageRequest.of(0, 1)) //符合查詢條件的文檔分頁,若是文檔比較大,能夠把這個分頁改小(不是聚合的分頁)
                .build();
        // 執行查詢
        AggregatedPage<TestEsDto> testEntities = elasticsearchTemplate.queryForPage(build, TestEsDto.class);

        // 取出聚合結果
        Nested agg = testEntities.getAggregations().get("personList");
        Terms terms = agg.getAggregations().get("sex");
        // 遍歷
        for (Terms.Bucket bucket : terms.getBuckets()) {
            Terms descTerms = bucket.getAggregations().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());
            }
        }

運行結果

1

相關文章
相關標籤/搜索