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

posted @ 2020-09-02 10:48  张占岭  阅读(4476)  评论(0编辑  收藏  举报