【ES】---ES的聚合(aggregations)

一、前言

聚合是对文档数据的统计、分析、计算。
注意:参与聚合的字段类型必须是:keyword、数值、日期、布尔,不能是分词字段。

1、聚合分类

在这里插入图片描述

2、聚合的实现方式

主要实现方式有:DSL实现、RestAPI实现。

二、RestAPI–bucket聚合案例1

案例1:现有一个ES表(content_info),主要包括如下几个关键字段
在这里插入图片描述

1、按照类型分bucket

public void bucketTest1(){
   
    
    
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder()
                .must(QueryBuilders.termQuery("doc_delete", Boolean.FALSE))
                .must(QueryBuilders.existsQuery("content_type"))
                .mustNot(QueryBuilders.termQuery("content_type.keyword", ""));

        AggregationBuilder aggregationBuilder = AggregationBuilders.terms("group_by_content_type")
                .script(new Script("doc['content_type.keyword'].value.toUpperCase()")).size(Integer.MAX_VALUE);

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.size(0);
        searchSourceBuilder.query(boolQueryBuilder);
        searchSourceBuilder.aggregation(aggregationBuilder);
        SearchRequest searchRequest = new SearchRequest("content_info");
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = null;
        try {
   
    
    
            searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        }catch (Exception e){
   
    
    
            log.error(" ex:{}",e.getMessage());
        }
        List<? extends Terms.Bucket> groupByFileExtensionList = ((Terms) searchResponse.getAggregations().get("group_by_content_type")).getBuckets();
        for (Terms.Bucket bucket : groupByFileExtensionList) {
   
    
    
            System.out.println("content_type id:"+bucket.getKeyAsString()+",value:"+bucket.getDocCount());
        }
        /**
      对content_type字段(String)进行桶聚合,得到的结果是 按照类型返回数组,每个类型会返回统计总数量!!
      ----这里 content_type是String类型,为了能聚合,加上keyword!!
         
         content_type id:PDF,value:165
         content_type id:XLSX,value:17
         content_type id:PRT,value:16
         content_type id:XLS,value:6
         content_type id:GLB,value:2
         content_type id:PNG,value:2
         */
}

由于在分组时,content_type存储的数据有大小写不统一现象,所以对该字段进行转换处理,代码写法如下:

AggregationBuilder aggregationBuilder = AggregationBuilders.terms("group_by_content_type")
        .script(new Script("doc['content_type.keyword'].value.toUpperCase()")).size(Integer.MAX_VALUE);

如果对应字段没什么要求,写法如下:

AggregationBuilder aggregationBuilder = AggregationBuilders.terms("group_by_id")
        .field("file_type.rele_id.keyword").size(Integer.MAX_VALUE);

2、按照(String)时间分bucket

难点:
ES中如果对time进行分bucket,这个时间是要Date类型。但这里是String类型存储,如果按照Date方式会报如下错误:Elasticsearch exception [type=illegal_argument_exception, reason=Text fields are not optimised for operations that require per-document field data like aggregations and sorting, so these operations are disabled by default. Please use a keyword field instead. Alternatively, set fielddata=true on [create_time] in order to load field data by uninverting the inverted index. Note that this can use significant memory.]
------要解决该问题,就需要对create_time字段特别处理,使用script()方法!

 public void bucketTest2() {
   
    
    
        BoolQueryBuilder boolQueryBuilder = 

猜你喜欢

转载自blog.csdn.net/xunmengyou1990/article/details/131878504