Es 根据时间分组聚合 (趋势图 折线图数据)

这篇博客介绍了DSL语句用于Elasticsearch的查询,包括时间范围过滤和特定字段的术语查询。同时展示了如何使用Java的DateHistogramAggregationBuilder和TermsAggregationBuilder来构建相同的查询,并解析响应以获取聚合结果。文章涵盖了时间桶聚合和状态统计,对于理解和应用Elasticsearch的聚合功能具有指导意义。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

DSL 语句

{
  "size": 0,
  "query": {
    "bool": {
      "must": [
        {
          "range": {
            "logtime": {
              "from": "2022-11-08T00:00:00.000Z",
              "to": null,
              "include_lower": true,
              "include_upper": true,
              "boost": 1
            }
          }
        },
        {
          "range": {
            "logtime": {
              "from": null,
              "to": "2022-11-08T23:59:59.999999999Z",
              "include_lower": true,
              "include_upper": true,
              "boost": 1
            }
          }
        },
        {
          "term": {
            "ip": {
              "value": "127.0.0.2",
              "boost": 1
            }
          }
        }
      ],
      "adjust_pure_negative": true,
      "boost": 1
    }
  },
  "track_total_hits": 2147483647,
  "aggregations": {
    "logtime": {
      "date_histogram": {    # date_histogram 按时间进行聚合
        "field": "logtime",      # 聚合字段
        "format": "HH:mm",		 # 时间格式化格式
        "fixed_interval": "1h",   # 间隔时间
        "offset": -28800000,    是因为es默认是按照UTC的时间进行查询的,所以需要减掉8小时 -8h
        "order": {
          "_key": "asc"
        },
        "keyed": false,
        "min_doc_count": 0,
        "extended_bounds": {    # 设置范围聚合的扩展边界 设置之后查询时间为空也会返回 确			  保聚合结果始终包含完整的范围,并避免数据丢失。
          "min": "now-30d",
          "max": "now-1"
        }
      },
      "aggregations": {
        "disposal_status": {
          "terms": {
            "field": "disposal_status",    # 根据状态再次聚合
            "size": 10,
            "min_doc_count": 1,
            "shard_min_doc_count": 0,
            "show_term_doc_count_error": false,
            "order": [
              {
                "_count": "desc"
              },
              {
                "_key": "asc"
              }
            ]
          }
        }
      }
    }
  }
}

java 实现

DateHistogramAggregationBuilder formatAgg = AggregationBuilders.dateHistogram(PortrayalConstant.LOG_TIME)
                //聚合字段
                .field(PortrayalConstant.LOG_TIME)
                //时间格式化
                .offset("-8h")
                // 返回0的数据
                .minDocCount(0L);

        if (StringUtils.isNotEmpty(eventAlarmDto.getSearchType()) && "1".equals(eventAlarmDto.getSearchType())) {
            formatAgg.fixedInterval(DateHistogramInterval.HOUR);
            formatAgg.format("HH:mm");
        } else {
            //如果查询时间按天则按小时分组
            formatAgg.fixedInterval(DateHistogramInterval.DAY);
            formatAgg.format("MM-dd")
            .extendedBounds(new LongBounds("now-30d", "now")));
        }

        TermsAggregationBuilder disposalAgg = 			  AggregationBuilders.terms(PortrayalConstant.DISPOSAL_STATUS).field(PortrayalConstant.DISPOSAL_STATUS);
        formatAgg.subAggregation(disposalAgg);
        searchSourceBuilder.aggregation(formatAgg);
        SearchRequest searchRequest = new SearchRequest(new String[]{PortrayalConstant.ES_EVENT_INDEX}, searchSourceBuilder);

        List<EventTrendVo> eventTrendVos = new ArrayList<>();
        try {
            SearchResponse response = inciDentEsMapper.search(searchRequest, RequestOptions.DEFAULT);
            Aggregations aggregations = response.getAggregations();
            ParsedDateHistogram dateHistogram = aggregations.get(PortrayalConstant.LOG_TIME);
            for (Histogram.Bucket bucket : dateHistogram.getBuckets()) {
                EventTrendVo trendVo = new EventTrendVo();
                String date = bucket.getKeyAsString();
                long total = bucket.getDocCount();
                trendVo.setLogTime(date);
                trendVo.setTotal(total);
                ParsedTerms statusTerms = bucket.getAggregations().get(PortrayalConstant.DISPOSAL_STATUS);
                for (Terms.Bucket statusBucket : statusTerms.getBuckets()) {
                    String status = statusBucket.getKeyAsString();
                    switch (status) {
                        case "0":
                            trendVo.setNotDisposed(statusBucket.getDocCount());
                            break;
                        case "1":
                            trendVo.setDisposed(statusBucket.getDocCount());
                            break;
                        case "2":
                            trendVo.setDisposal(statusBucket.getDocCount());
                            break;
                        default:
                            trendVo.setDisposal(0L);
                            break;
                    }
                }
                eventTrendVos.add(trendVo);
            }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值