ElasticSearch 2 (31) - 信息聚合系列之时间处理

ElasticSearch 2 (31) - 信息聚合系列之时间处理

摘要

如果说搜索是 Elasticsearch 里最受欢迎的功能,那么按时间创建直方图一定排在第二位。为什么需要使用时间直方图?

版本

elasticsearch版本: elasticsearch-2.x

内容

如果说搜索是 Elasticsearch 里最受欢迎的功能,那么按时间创建直方图一定排在第二位。为什么需要使用时间直方图?

假设我们的数据都有时间戳,无论我们的数据是 Apache 日志事件,或是股票交易日期,还是棒球赛时间,任何与时间戳有关的数据都可以从时间直方图里得到有价值的信息。通常我们希望根据时间来创建度量:

  • 本年度每月汽车销量是多少?
  • 过去 12 小时股价的变化?
  • 过去一周中网站每小时内的平均响应时延是多少?

普通的直方图通常以条状图表表示,日期直方图则会转换成折线图用来表示时间序列。很多公司使用 Elasticsearch 只为了分析时间序列信息。date_histogram 桶正是我们想要的油条和豆浆。

date_histogram 与一般直方图的工作方式类似,不同的是它没有基于数值字段表示数值区间,而是基于时间范围创建桶。因此,每个桶代表时间轴上的一段(比如:1 月 或 2.5 天)。

普通的直方图可以展示时间吗?

技术上讲是可以的。一个普通的直方图桶可以展示时间,但是它并不没有与日历相关的概念。运用 date_histogram,我们可以指定间隔为 1 月,这样我们可以知道二月比十二月的时间短。date_histogram 还有一个优势就是它可以与时区联用,这让我们可以按照用户所处时区来定制图形
报表,而不是服务器时间。

普通的直方图将时间解释成数字,这意味着我们必须以毫秒为单位指定间隔。这样聚合对日历时间间隔没有任何概念,也无法使用日期信息。

我们第一个示例会创建一个简单的折线图表来回答问题:每个月的汽车销量是多少?

  GET /cars/transactions/_search
  {
     "size" : 0,
     "aggs": {
        "sales": {
           "date_histogram": {
              "field": "sold",
              "interval": "month", #1
              "format": "yyyy-MM-dd" #2
           }
        }
     }
  }

#1 这个间隔是日历语境下的值(例如:每个桶表示一个月)。

#2 为其提供一个时间格式这样能显示的更好看。

我们的查询有单个聚合,每个月创建一个桶,为我们提供每月汽车销售的数量。加上 format 参数可以让桶的键值更“好看”。在内部,日期是以简单数字形式表示的,这会让 UI 设计师感到抓狂,不过,可以通过指定一个通用的日期格式获得更好的格式。

响应返回如预期一样但是有个小意外(看看能否发现它):

  {
     ...
     "aggregations": {
        "sales": {
           "buckets": [
              {
                 "key_as_string": "2014-01-01",
                 "key": 1388534400000,
                 "doc_count": 1
              },
              {
                 "key_as_string": "2014-02-01",
                 "key": 1391212800000,
                 "doc_count": 1
              },
              {
                 "key_as_string": "2014-05-01",
                 "key": 1398902400000,
                 "doc_count": 1
              },
              {
                 "key_as_string": "2014-07-01",
                 "key": 1404172800000,
                 "doc_count": 1
              },
              {
                 "key_as_string": "2014-08-01",
                 "key": 1406851200000,
                 "doc_count": 1
              },
              {
                 "key_as_string": "2014-10-01",
                 "key": 1412121600000,
                 "doc_count": 1
              },
              {
                 "key_as_string": "2014-11-01",
                 "key": 1414800000000,
                 "doc_count": 2
              }
           ]
  ...
  }

聚合被完整的呈现出来,正如看到的,我们有用来表示每个月信息的桶,每月文档的数量信息,以及美化过后的 key_as_string

返回空桶(Returning Empty Buckets)

注意到响应中有什么奇怪的吗?

对,正是这样。我们缺失了一些月份的信息,date_histogram(普通 histogram 也是如此)只返回文档数目非零的那些桶。

这表示直方图以最小形式作为响应结果。通常,这并不是我们想要的行为。在很多应用中,我们希望直接将响应数据传入图形库而不要做任何后续处理。

本质上说,即使数目为零我们也希望桶的信息能出现在结果中,可以设置两个参数来实现这个行为:

  GET /cars/transactions/_search
  {
     "size" : 0,
     "aggs": {
        "sales": {
           "date_histogram": {
              "field": "sold",
              "interval": "month",
              "format": "yyyy-MM-dd",
              "min_doc_count" : 0, #1
              "extended_bounds" : { #2
                  "min" : "2014-01-01",
                  "max" : "2014-12-31"
              }
           }
        }
     }
  }

#1 参数强制返回空桶。

#2 参数强制返回全年数据。

两个附加的参数会强制响应返回全年所有月份的信息,无论它们文档数目如何。min_doc_count 哼容易理解:即使桶是空的也会强制作为结果返回。

需要对 extended_bounds 参数做些许解释。 min_doc_count 参数强制空桶信息返回,但是 Elasticsearch 默认只会返回处于最小与最大值之间的数据。

所以如果数据在四月和七月之间,我们的桶只会表示这之间的月份(无论是不是空)。为了得到全年的信息,我们需要告诉 Elasticsearch 我们想要得到那些处于最小值和最大值之外的桶的信息。

extended_bounds 参数就是做这件事情,一旦我们增加了这两个设置,我们就能得到可以直接传入图形库的输出,图形的显示如图 Figure 37, “Cars sold over time”.

Figure 37. Cars sold over time

613455-20160324111306339-2127658526.png

示例扩展(Extended Example)

正如无数次见到的那样,可以嵌套使用桶获得更复杂的行为。为了举例说明,我们可以创建一个聚合按季度展示所有汽车品牌总销售额,同时按季度、按每个汽车品牌计算销售总额,这样我们就能知道哪种车型能为我们的生意带来更多收益:

  GET /cars/transactions/_search
  {
     "size" : 0,
     "aggs": {
        "sales": {
           "date_histogram": {
              "field": "sold",
              "interval": "quarter", #1
              "format": "yyyy-MM-dd",
              "min_doc_count" : 0,
              "extended_bounds" : {
                  "min" : "2014-01-01",
                  "max" : "2014-12-31"
              }
           },
           "aggs": {
              "per_make_sum": {
                 "terms": {
                    "field": "make"
                 },
                 "aggs": {
                    "sum_price": {
                       "sum": { "field": "price" } #2
                    }
                 }
              },
              "total_sum": {
                 "sum": { "field": "price" } #3
              }
           }
        }
     }
  }

#1 注意我们将间隔从 month 改成了 quarter

#2 按汽车品牌分别求和。

#3 所有汽车品牌总和。

响应返回(结果的少量片段):

  {
  ....
  "aggregations": {
     "sales": {
        "buckets": [
           {
              "key_as_string": "2014-01-01",
              "key": 1388534400000,
              "doc_count": 2,
              "total_sum": {
                 "value": 105000
              },
              "per_make_sum": {
                 "buckets": [
                    {
                       "key": "bmw",
                       "doc_count": 1,
                       "sum_price": {
                          "value": 80000
                       }
                    },
                    {
                       "key": "ford",
                       "doc_count": 1,
                       "sum_price": {
                          "value": 25000
                       }
                    }
                 ]
              }
           },
  ...
  }

我们将响应的结果作为图形的输入,展现总售价的折线图,并按季度显示每个汽车品牌的销售总额,如图 Figure 38, “Sales per quarter, with distribution per make”

Figure 38. Sales per quarter, with distribution per make

613455-20160324113208761-1387889585.png

有限空间(The Sky’s the Limit)

这些都是显而易见的简单示例,但是要用图表表示聚合总会有所限制。例如,Figure 39, “Kibana—a real time analytics dashboard built with aggregations” 图中呈现了 Kibana 的一个仪表盘里面展示了丰富的合信息。

Figure 39. Kibana—a real time analytics dashboard built with aggregations

613455-20160324130848558-70392041.png

因为聚合的实时性,它们易于查询、处理和交互。这对于非技术员工和分析师来说是理想的工具,因为他们可以分析数据,而知道如何创建 Hadoop 任务。

要创建像 Kibana 这样的强大仪表盘,可能需要理解一些更高级的概念比如:限定范围、过滤以及聚合排序。

参考

elastic.co:
Looking at Time

转载于:https://www.cnblogs.com/richaaaard/p/5314705.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值