相似于直方图的多桶聚合,但它只能应用于日期值,因为在Elasticsearch内部将日期表示为long
值,所以也能够在日期上使用普通的histogram
,但准确性会受到影响,缘由是基于时间的间隔不是固定的(想一想闰年和一个月的天数),所以,咱们须要对基于时间的数据提供特殊支持。从功能的角度来看,这个直方图支持与普通直方图相同的特性,主要的区别是间隔能够由日期/时间表达式指定。html
请求桶间隔一个月。数据库
POST /sales/_search?size=0 { "aggs" : { "sales_over_time" : { "date_histogram" : { "field" : "date", "interval" : "month" } } } }
时间间隔可用的表达式:year
(1y
)、quarter
(1q
)、month
(1M
)、week
(1w
)、day
(1d
)、hour
(1h
)、minute
(1M
)、second
(1s
)。数组
时间值也能够经过时间单位解析所支持的缩写来指定,注意,不支持小数时间值,可是你能够经过转移到另外一个时间单位来解决这个问题(例如,1.5h
能够被指定为90m
),还要注意,大于天的时间间隔不支持任意值,但只能是一个单位大(例如,1y
是有效的,2y
不是)。less
POST /sales/_search?size=0 { "aggs" : { "sales_over_time" : { "date_histogram" : { "field" : "date", "interval" : "90m" } } } }
在内部,日期被表示为64位数字,表示从纪元开始算起的时间戳,这些时间戳做为桶的key
返回,key_as_string
是与使用format
参数指定的格式转换成格式化日期字符串相同的时间戳:elasticsearch
若是没有指定
format
,那么它将使用字段映射中指定的第一个日期格式。
POST /sales/_search?size=0 { "aggs" : { "sales_over_time" : { "date_histogram" : { "field" : "date", "interval" : "1M", "format" : "yyyy-MM-dd" } } } }
"format" : "yyyy-MM-dd"
=> 支持表达日期格式模式ide
响应:ui
{ ... "aggregations": { "sales_over_time": { "buckets": [ { "key_as_string": "2015-01-01", "key": 1420070400000, "doc_count": 3 }, { "key_as_string": "2015-02-01", "key": 1422748800000, "doc_count": 2 }, { "key_as_string": "2015-03-01", "key": 1425168000000, "doc_count": 2 } ] } } }
在Elasticsearch中日期时间被存储在UTC,默认状况下,全部桶和四舍五入都是在UTC中完成的,可使用time_zone
参数指示桶使用不一样的时区。code
时区能够指定为ISO 8601 UTC偏移量(例如+01:00
或-08:00
),也能够指定为时区id,这是TZ数据库(如America/Los_Angeles
)中使用的标识符。orm
考虑下面的示例:htm
PUT my_index/_doc/1?refresh { "date": "2015-10-01T00:30:00Z" } PUT my_index/_doc/2?refresh { "date": "2015-10-01T01:30:00Z" } GET my_index/_search?size=0 { "aggs": { "by_day": { "date_histogram": { "field": "date", "interval": "day" } } } }
若是没有指定时区,则使用UTC,这将致使将这两个文档放入同一天的桶中,该桶从2015年10月1日午夜UTC开始:
{ ... "aggregations": { "by_day": { "buckets": [ { "key_as_string": "2015-10-01T00:00:00.000Z", "key": 1443657600000, "doc_count": 2 } ] } } }
若是指定了-01:00
的time_zone
,那么午夜从UTC午夜前一小时开始:
GET my_index/_search?size=0 { "aggs": { "by_day": { "date_histogram": { "field": "date", "interval": "day", "time_zone": "-01:00" } } } }
如今第一个文档落入2015年9月30日的桶,第二个文档落入2015年10月1日的桶:
{ ... "aggregations": { "by_day": { "buckets": [ { "key_as_string": "2015-09-30T00:00:00.000-01:00", "key": 1443574800000, "doc_count": 1 }, { "key_as_string": "2015-10-01T00:00:00.000-01:00", "key": 1443661200000, "doc_count": 1 } ] } } }
key_as_string
值表示在指定时区中天天的午夜。
当使用遵循DST(夏令时)更改的时区时,与这些更改发生的时刻接近的桶的大小可能与使用interval
预期的大小略有不一样。例如,考虑在CET
时区启动DST:2016年3月27日凌晨2点,时钟拨快1小时至当地时间凌晨3点,当使用day
做为interval
时,覆盖当天的桶将只保存23个小时的数据,而其余桶一般是24小时。对于较短的间隔,如12h,也是如此,在这里,当DST转变发生时,咱们在3月27日早上只有一个11小时的桶。
offset
参数用于经过指定的正(+
)或负偏移(-
)的持续时间来更改每一个桶的起始值,例如1h
为1小时或1d
为一天,有关更多可能的持续时间选项,请参阅时间单位。
例如,当使用day
的间隔时,每一个桶从午夜运行到午夜,将offset
参数设置为+6h
将更改每一个桶从早上6点运行到早上6点:
PUT my_index/_doc/1?refresh { "date": "2015-10-01T05:30:00Z" } PUT my_index/_doc/2?refresh { "date": "2015-10-01T06:30:00Z" } GET my_index/_search?size=0 { "aggs": { "by_day": { "date_histogram": { "field": "date", "interval": "day", "offset": "+6h" } } } }
上面的请求将文档分组为从早上6点开始的桶,而不是从午夜开始的单个桶:
{ ... "aggregations": { "by_day": { "buckets": [ { "key_as_string": "2015-09-30T06:00:00.000Z", "key": 1443592800000, "doc_count": 1 }, { "key_as_string": "2015-10-01T06:00:00.000Z", "key": 1443679200000, "doc_count": 1 } ] } } }
在进行time_zone
调整以后,计算每一个桶的起始offset
。
将keyed
标志设置为true
将把惟一的字符串键与每一个桶关联起来,并以hash而不是数组的形式返回范围:
POST /sales/_search?size=0 { "aggs" : { "sales_over_time" : { "date_histogram" : { "field" : "date", "interval" : "1M", "format" : "yyyy-MM-dd", "keyed": true } } } }
响应:
{ ... "aggregations": { "sales_over_time": { "buckets": { "2015-01-01": { "key_as_string": "2015-01-01", "key": 1420070400000, "doc_count": 3 }, "2015-02-01": { "key_as_string": "2015-02-01", "key": 1422748800000, "doc_count": 2 }, "2015-03-01": { "key_as_string": "2015-03-01", "key": 1425168000000, "doc_count": 2 } } } } }
与普通直方图同样,支持文档级别脚本和值级别脚本,还可使用order
设置控制返回的桶的顺序,并基于min_doc_count
设置过滤返回的桶(默认状况下,将返回匹配文档的第一个桶和最后一个桶之间的全部桶)。这个直方图还支持extended_bounds
设置,它容许扩展直方图的界限超过数据自己(关于为何要这样作的更多信息,请参阅此处的解释)。
missing
参数定义了如何处理缺失值的文档,默认状况下,它们将被忽略,但也能够将它们视为有值来处理。
POST /sales/_search?size=0 { "aggs" : { "sale_date" : { "date_histogram" : { "field" : "date", "interval": "year", "missing": "2000/01/01" } } } }
publish_date
字段中没有值的文档将落入具备值为2000-01-01
的文档的同一个桶。
默认状况下,返回的桶按key
升序排序,不过可使用order
设置控制顺序行为,支持与Terms聚合相同的order
功能。
在6.0.0中已弃用
使用
_key
而不是_time
来根据它们的日期/键来排序桶。
在某些状况下,日期直方图不能帮助咱们,例如,当咱们须要经过星期几聚合结果时,在这种状况下,为了克服这个问题,咱们可使用一个返回星期几的脚本:
POST /sales/_search?size=0 { "aggs": { "dayOfWeek": { "terms": { "script": { "lang": "painless", "source": "doc['date'].value.dayOfWeek" } } } } }
响应:
{ ... "aggregations": { "dayOfWeek": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [ { "key": "7", "doc_count": 4 }, { "key": "4", "doc_count": 3 } ] } } }
响应将包含以星期为键的全部桶:1为星期一,2为星期二...7为星期日。