es 根据父文档,对子文档聚合

9 篇文章 1 订阅

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-children-aggregation.html

上面链接是官方文档对于父子文档的聚合示例,解释还是很清楚的。

下是我自己根据官网进行的聚合(就不提供数据了,只是我的模仿而已)

    /*
     * ******************************* 此处ES查询语句形如 **************************************/
         GET company_info/_search
        {
          "size": 0,
          "aggregations": {

            "top_district":{
              "terms": {
                "field": "districtName"
              } ,
              "aggs": {
                "to-person": {
                  "children": {
                    "type": "person"
                  } ,
                  "aggs": {
                    "per_state": {
                      "terms": {
                        "field": "personCerts"
                      }
                    }
                  }
                }
              }
            }
          }
        }

结果,为了一张截图展示更多,对部分结果做了折叠处理,折叠部分和下面未折叠部分数据格式一致。

Java 父子聚合用到的是 

 

具体代码如下

    public Map<String,List<Map<String,Long>>> aggregationDistrictPerson() throws Exception {
        TermsAggregationBuilder perStats = AggregationBuilders.terms("per_state").field("personCerts").size(10);
        //这句就是针对子文档的聚合了
        ChildrenAggregationBuilder childrenAggregation = JoinAggregationBuilders.children("to-person","person").subAggregation(perStats) ;

        TermsAggregationBuilder districtStats = AggregationBuilders.terms("top_district").field("districtName").subAggregation(childrenAggregation) ;

        Aggregations aggregations  = esSearchService.aggregate(districtStats,matchAllQuery(),ES_INDEX);

        Map<String, Aggregation> aggMap = aggregations.asMap();
        Terms termAgg = (Terms) aggMap.get("top_district");

        List<? extends Terms.Bucket> buckets = termAgg.getBuckets();

        Map<String,List<Map<String,Long>>> resultMap = new HashMap<>();

        buckets.forEach(bucket -> {
            List<Map<String,Long>> listMap = new ArrayList<>();
            Aggregations bucketAggregations = bucket.getAggregations();
            Map<String, Aggregation> aggregationMap = bucketAggregations.asMap() ;
            ParsedChildren toPerson = (ParsedChildren) aggregationMap.get("to-person");
            Aggregations termAggregations = toPerson.getAggregations();
            Map<String, Aggregation> termAggregationMap = termAggregations.asMap() ;

            Terms perState = (Terms) termAggregationMap.get("per_state");
            List<? extends Terms.Bucket> perStateBuckets = perState.getBuckets();

            Map<String,Long> tbMap = new HashMap<>();
            perStateBuckets.forEach(tb->tbMap.put(tb.getKey().toString(),tb.getDocCount()));
            listMap.add(tbMap);
            resultMap.put(bucket.getKey().toString(),listMap);
        });

        log.info(buckets);
        log.info(aggregations);

        return resultMap ;
    }

整理后,结果形如

Elasticsearch中,可以使用Nested和Parent/Child两种方式来进行文档聚合查询。 1. Nested方式 使用Nested方式进行文档聚合查询需要先将文档嵌套在文档中,然后使用Nested类型进行查询。Nested类型会将嵌套在文档中的文档看作一个独立的文档进行处理。 例如,如果我们有一个文档(books)和一个文档(authors),其中每个book可以有多个author,那么我们可以使用以下查询来对每个book的author进行聚合: ``` { "size": 0, "aggs": { "books": { "nested": { "path": "authors" }, "aggs": { "authors": { "terms": { "field": "authors.name" } } } } } } ``` 这个查询会先使用Nested类型指定文档路径(authors),然后使用terms aggregation对每个author的name进行聚合。 2. Parent/Child方式 使用Parent/Child方式进行文档聚合查询需要先将文档文档分别建立索引,并且使用Parent字段来关联两个索引。然后,使用Has Child或Has Parent类型进行查询。 例如,如果我们有一个文档(books)和一个文档(authors),其中每个book可以有多个author,那么我们需要先将books和authors分别建立索引,并且使用book的ID作为author的Parent字段。然后,我们可以使用以下查询来对每个book的author进行聚合: ``` { "size": 0, "aggs": { "books": { "terms": { "field": "books.title" }, "aggs": { "authors": { "children": { "type": "authors", "filter": { "match_all": {} } }, "aggs": { "names": { "terms": { "field": "authors.name" } } } } } } } } ``` 这个查询会先使用terms aggregation对books进行聚合,然后使用Has Child类型指定文档类型(authors),并使用match_all filter过滤所有文档。最后,使用terms aggregation对每个author的name进行聚合
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值