一尘不染

使用Elasticsearch按时间划分的累计流量

elasticsearch

我正在从大量客户端应用程序接收请求/事件。我想使用elasticsearch找出我的最高流量点。

我尝试过的一件事是使用嵌套的直方图进行过滤器聚合,然后使用嵌套的“术语”聚合通过脚本字段获取一天中不同的时间。以下是我的尝试,它的执行效果非常好(正如我期望的那样,因为我正在为每个文档执行脚本)。

{
  "aggs": {
    "sites_within_range": {
      "filter" : { 
        "range" : { 
          "occurred" : { 
            "gt" : "now-1M"
          }
        } 
      },

      "aggs": {
        "sites_over_time": {
          "date_histogram": {
            "field": "occurred",
            "interval": "week"
          },
          "aggs":{
            "site_names": {
              "terms": {
                "script": "doc['occurred'].date.getHourOfDay()",
                "size": 10000
              }
            }
          }
        }
      }

    }
  }
}

我还考虑过将要查询的日期元素存储为文档的不同部分,例如:

{
    "date": "actual datetime",
    "day": "monday",
    "hour": 8
    "minute": 37
}

这也闻起来像是对我的错误答案。


经过一些调查,看起来我可能对1.1中的新基数/百分比聚合感兴趣?


阅读 394

收藏
2020-06-22

共1个答案

一尘不染

在该线程中已经解决了同类问题。

为使解决方案适应您的问题,我们需要编写一个脚本以将日期转换为一天中的小时:

Date date = new Date(doc['created_at'].value) ; 
java.text.SimpleDateFormat format = new java.text.SimpleDateFormat('HH');
format.format(date)

并在查询中使用它:

{
    "aggs": {
        "perWeekDay": {
            "filter" : { 
                "range" : { 
                    "occurred" : { 
                        "gt" : "now-1M"
                    }
                } 
            },
            "aggs": {
                "terms": {
                    "script": "Date date = new Date(doc['created_at'].value) ;java.text.SimpleDateFormat format = new java.text.SimpleDateFormat('HH');format.format(date)"
            }
        }
    }
}

您一天中的流量就很大。

注意: 将小时/天/分钟存储在文档中是进行此类汇总的最有效方法。我的答案假设您不想存储该信息。脚本通常效率不高。

2020-06-22