【问题标题】:Group by modified timestamp and return max value from Elasticsearch按修改后的时间戳分组并从 Elasticsearch 返回最大值
【发布时间】:2014-08-15 08:26:14
【问题描述】:

我正在运行 Elasticsearch v1.2.2。

我有一个这样的文档集合

[
  { id: 1, source: { host: 'test.localhost', timestamp: 1407937236, loading_time: 2.841917 } },
  { id: 2, source: { host: 'test.localhost', timestamp: 1407937262, loading_time: 2.009191 } },
  { id: 3, source: { host: 'test.localhost', timestamp: 1407937322, loading_time: 2.084986 } },
  { id: 4, source: { host: 'test.localhost', timestamp: 1407937382, loading_time: 2.869245 } },
  { id: 5, source: { host: 'test.localhost', timestamp: 1407937442, loading_time: 2.559648 } },
  ...
]

(基本上所有分钟我都对内部主机运行测试,返回加载时间。)

现在我想生成一个概览图:

  • 按 30 分钟分组的时间戳
  • 返回(该分组的)最大加载时间
  • host 是特定的东西
  • 在特定时间戳范围之间
  • 按时间戳排序

由于我是 Elasticsearch 的新手,我什至不知道这一切是否可行。

在 MySQL 中是这样的

SELECT (FLOOR(`timestamp` / 1800) * 1800) AS timestamp
       MAX(`loading_time`) AS loading_time
FROM `elasticsearch_table`
GROUP BY (FLOOR(`timestamp` / 1800) * 1800)
WHERE `host` = 'test.localhost'
AND `timestamp` BETWEEN 1407937236 AND 1407937442
ORDER BY `timestamp` ASC

(不确定这个 MySQL 查询是否有效,但它应该让您了解我想要实现的目标。)

【问题讨论】:

    标签: mysql elasticsearch


    【解决方案1】:

    用于此类计算的功能在 Elasticsearch 中称为 aggregations

    下面是一些聚合,应该适合您对每个步骤的需要:

    • 按 30 分钟分组的时间戳 => date_histogram 聚合,间隔为 30m
    • 返回(该分组的)最大 loading_time => max 加载时间聚合。
    • 其中主机是特定的东西 => filter 聚合与 主机上的term filter
    • 在特定时间戳范围之间 => 另一个带有 range 过滤器的过滤器聚合。
    • 按时间戳排序

    棘手的部分是正确嵌套不同的聚合。你应该在一个小数据集上做一些测试来检查。

    试试这样的:

    GET test/collection/_search?search_type=count
    {
      "aggs": {
        "filter_by_host":{
          "filter": {
            "and": {
              "filters": [
                {"term": {"host": "test.localhost"}},
                {"range": {"timestamp": {
                  "from": 1407937230000,               
                  "to": 1407937400000
                }}}
              ]
            }
          },
          "aggs": {
            "date": {
              "date_histogram": {
                "field": "timestamp",
                "interval": "2m"
              },
              "aggs": {
                "max_loading_time": {
                 "max" : {"field" : "loading_time" }}
                }
              }
            }
          }
        }
      }
    }
    

    间隔只有 2 分钟,并且选择范围边界只是为了从数据集中排除第五个文档,以查看它的有效过滤。

    唯一缺少的部分是排序:您不能对计数结果进行排序。

    请求输出:

    {
        ...
       "aggregations": {
          "filter_by_host": {
             "doc_count": 4,
             "date": {
                "buckets": [
                   {
                      "key_as_string": "2014-08-13T13:40:00.000Z",
                      "key": 1407937200000,
                      "doc_count": 2,
                      "max_loading_time": {
                         "value": 2.841917
                      }
                   },
                   {
                      "key_as_string": "2014-08-13T13:42:00.000Z",
                      "key": 1407937320000,
                      "doc_count": 2,
                      "max_loading_time": {
                         "value": 2.869245
                      }
                   }
                ]
             }
          }
       }
    }
    

    【讨论】:

    • 天哪,你真是个天才!非常感谢!唯一对我不起作用的部分是“date_histogram”部分。我将其更改为'histogram': { 'field': 'timestamp', 'interval': 600 }(600 = 10 分钟)。我认为这是因为我正在使用自己的时间戳字段。
    • 不客气!时间戳的问题可能是因为它是以秒为单位的时间戳。在测试时,我必须将它乘以 1000 才能使其与 date_histogram 一起使用。但是,直方图聚合也可以:)
    猜你喜欢
    • 2019-11-25
    • 2016-05-28
    • 2013-06-22
    • 1970-01-01
    • 2014-02-07
    • 1970-01-01
    • 2020-02-21
    • 2011-10-13
    • 1970-01-01
    相关资源
    最近更新 更多