【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() {
   
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,以下是一个简单的ElasticSearch聚合的Java API示例: ```java import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.Client; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval; import org.elasticsearch.search.aggregations.bucket.histogram.Histogram; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.metrics.sum.Sum; import org.elasticsearch.search.aggregations.metrics.valuecount.ValueCount; import static org.elasticsearch.index.query.QueryBuilders.rangeQuery; public class ElasticSearchAggregationExample { public static void main(String[] args) { // 创建ElasticSearch客户端 Client client = // ...; // 构建查询条件 QueryBuilder query = QueryBuilders.boolQuery() .must(rangeQuery("timestamp").gte("2022-01-01T00:00:00").lte("2022-01-31T23:59:59")); // 构建聚合条件 AggregationBuilder aggregation = AggregationBuilders .dateHistogram("sales_over_time") .field("timestamp") .dateHistogramInterval(DateHistogramInterval.DAY) .subAggregation( AggregationBuilders .terms("product_types") .field("product_type") .subAggregation( AggregationBuilders.sum("total_sales").field("sales"), AggregationBuilders.count("transaction_count").field("transaction_id") ) ); // 执行查询 SearchResponse response = client.prepareSearch("my_index") .setQuery(query) .addAggregation(aggregation) .execute() .actionGet(); // 解析聚合结果 Histogram histogram = response.getAggregations().get("sales_over_time"); for (Histogram.Bucket bucket : histogram.getBuckets()) { System.out.println("Date: " + bucket.getKeyAsString()); Terms productTypes = bucket.getAggregations().get("product_types"); for (Terms.Bucket productType : productTypes.getBuckets()) { System.out.println("Product Type: " + productType.getKeyAsString()); Sum totalSales = productType.getAggregations().get("total_sales"); System.out.println("Total Sales: " + totalSales.getValue()); ValueCount transactionCount = productType.getAggregations().get("transaction_count"); System.out.println("Transaction Count: " + transactionCount.getValue()); } } // 关闭客户端 client.close(); } } ``` 这个示例通过ElasticSearch的Java API执行了一个聚合,其中包含了两层嵌套聚合,分别按照日期和产品类型对销售数据进行了汇总,输出了每个日期和产品类型的销售总额和交易次数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DreamBoy_W.W.Y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值