Nested是一种嵌套文档,类似于父子文档,它可以将与主文档有关的数据进行存储,可以把它理解成一张子表
,它的查询和聚合性能很好;更新性能一般。
下面是测试使用的数据结构,一个包含Nested属性的实体
@Document(indexName = "esdto", type = "esdto")@Data@ToString(callSuper = true)@AllArgsConstructor@NoArgsConstructorpublic 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; }}
存储的数据如图
聚合代码
// 创建一个查询条件对象 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()); } }
没有评论:
发表评论