Date Range Aggregation是一个专用于时间类型数据的范围聚合。它和 range aggregation 主要区别在与from
和 to
的值可以用日期表达式, 也可以指定返回体中的 from
和 to
的格式。注意,聚合的每个范围会包含from
但是排除to
例如:
POST /sales/_search?size=0
{
"aggs": {
"range": {
"date_range": {
"field": "date",
"format": "MM-yyy",
"ranges": [
{ "to": "now-10M/M" },
{ "from": "now-10M/M" }
]
}
}
}
}
说明:现在减去10个月,并跳转到月份的开始时间。
在上面的例子里, 我们创建了2个范围分组,第一个会包含10个月之前所有的文档,第二个会包含10个月之前之后的所有文档。
响应如下:
{
...
"aggregations": {
"range": {
"buckets": [
{
"to": 1.4436576E12,
"to_as_string": "10-2015",
"doc_count": 7,
"key": "*-10-2015"
},
{
"from": 1.4436576E12,
"from_as_string": "10-2015",
"doc_count": 0,
"key": "10-2015-*"
}
]
}
}
}
missing参数用于定义没有值的文档应该怎么处理。默认情况,它们会被忽视掉,当然也可以当作有值来处理 我们需要在映射中为字段先指明缺省值。
POST /sales/_search?size=0
{
"aggs": {
"range": {
"date_range": {
"field": "date",
"missing": "1976/11/30",
"ranges": [
{
"key": "Older",
"to": "2016/02/01"
},
{
"key": "Newer",
"from": "2016/02/01",
"to" : "now/d"
}
]
}
}
}
}
文档中date
字段取值为空的会有"1899-12-31"
默认值,然后会被划分到"Older"
分组 。
注意
信息源于JodaDate
所有ASCII字母保留为格式表达式字母,其定义如下:
Symbol | Meaning | Presentation | Examples |
---|---|---|---|
G | era | text | AD |
C | century of era (>=0) | number | 20 |
Y | year of era (>=0) | year | 1996 |
x | weekyear | year | 1996 |
w | week of weekyear | number | 27 |
e | day of week | number | 2 |
E | day of week | text | Tuesday; Tue |
y | year | year | 1996 |
D | day of year | number | 189 |
M | month of year | month | July; Jul; 07 |
d | day of month | number | 10 |
a | halfday of day | text | PM |
K | hour of halfday (0~11) | number | 0 |
h | clockhour of halfday (1~12) | number | 12 |
H | hour of day (0~23) | number | 0 |
k | clockhour of day (1~24) | number | 24 |
m | minute of hour | number | 30 |
s | second of minute | number | 55 |
S | fraction of second | number | 978 |
z | time zone | text | Pacific Standard Time; PST |
Z | time zone offset/id | zone | -0800; -08:00; America/Los_Angeles |
’ | escape for text | delimiter | ‘’ |
表达式字母的数量决定了格式。
XX | 说明 |
---|---|
Text | 如果表达式字母的数目是4或更多,则使用完整的形式;否则,如果可用的话,可以使用短或缩写形式。 |
Number | 数字的最小表示。 |
Year | 年份和周岁字段的数字表示是专门处理的。例如,如果Y的计数为2,则年将显示为本世纪的零基年,这是两位数。 |
Month | 3个或者以上使用text 否则使用number |
Zone | Z输出没有冒号偏移,ZZ用冒号、ZZZ或更多的输出输出zone id. |
Zone names | 无法解析时区名称(Z)。 |
表达式中的任何字符不在[A.Z]和[A.Z]的范围内,将被视为引用文本。例如, :, ., ’ , '# and ? 将出现在生成的时间文本中,即使它们不包含在单引号中。
time_zone
参数可以把日期的时区转换为UTC
时区可以指定为ISO 8601 UTC
偏移量(例如+01:00或-08:00),或者指定为来自TZ数据库的http://www.joda.or g/joda-time/time zones.html[Zone id]之一。
time_zone
参数也可以应用于日期表达式中。作为一个例子,在CET时区开始一天的循环,你可以做以下事情:
POST /sales/_search?size=0
{
"aggs": {
"range": {
"date_range": {
"field": "date",
"time_zone": "CET",
"ranges": [
{ "to": "2016/02/01" },
{ "from": "2016/02/01", "to" : "now/d" },
{ "from": "now/d" }
]
}
}
}
}
日期将被转换为 2016-02-15T00:00:00.000+01:00.
now/d
被四舍五入为 CET时区一天的开始。
设置 keyed
为 true
会将每个分组和一个独一无二的key关联并将返回作为hash返回而不是array:
POST /sales/_search?size=0
{
"aggs": {
"range": {
"date_range": {
"field": "date",
"format": "MM-yyy",
"ranges": [
{ "to": "now-10M/M" },
{ "from": "now-10M/M" }
],
"keyed": true
}
}
}
}
响应如下:
{
...
"aggregations": {
"range": {
"buckets": {
"*-10-2015": {
"to": 1.4436576E12,
"to_as_string": "10-2015",
"doc_count": 7
},
"10-2015-*": {
"from": 1.4436576E12,
"from_as_string": "10-2015",
"doc_count": 0
}
}
}
}
}
也支持为每个范围自定义key:
POST /sales/_search?size=0
{
"aggs": {
"range": {
"date_range": {
"field": "date",
"format": "MM-yyy",
"ranges": [
{ "from": "01-2015", "to": "03-2015", "key": "quarter_01" },
{ "from": "03-2015", "to": "06-2015", "key": "quarter_02" }
],
"keyed": true
}
}
}
}
响应如下:
{
...
"aggregations": {
"range": {
"buckets": {
"quarter_01": {
"from": 1.4200704E12,
"from_as_string": "01-2015",
"to": 1.425168E12,
"to_as_string": "03-2015",
"doc_count": 5
},
"quarter_02": {
"from": 1.425168E12,
"from_as_string": "03-2015",
"to": 1.4331168E12,
"to_as_string": "06-2015",
"doc_count": 2
}
}
}
}
}
Filter Aggregation是一个在当前索引中过滤所有满足匹配条件文档的单分组聚合。通常用于从当前聚合得到一个具体的文档集。
例如:
POST /sales/_search?size=0
{
"aggs" : {
"t_shirts" : {
"filter" : { "term": { "type": "t-shirt" } },
"aggs" : {
"avg_price" : { "avg" : { "field" : "price" } }
}
}
}
}
在上面的例子我们计算了 t-shirt产品的平均价格.
响应如下:
{
...
"aggregations" : {
"t_shirts" : {
"doc_count" : 3,
"avg_price" : { "value" : 128.33333333333334 }
}
}
}
Filters Aggregation是一个多分组聚合,每个分组关联一个过滤条件,并收集所有满足自身过滤条件的文档。
例如:
PUT /logs/_doc/_bulk?refresh
{ "index" : { "_id" : 1 } }
{ "body" : "warning: page could not be rendered" }
{ "index" : { "_id" : 2 } }
{ "body" : "authentication error" }
{ "index" : { "_id" : 3 } }
{ "body" : "warning: connection timed out" }
GET logs/_search
{
"size": 0,
"aggs" : {
"messages" : {
"filters" : {
"filters" : {
"errors" : { "match" : { "body" : "error" }},
"warnings" : { "match" : { "body" : "warning" }}
}
}
}
}
}
上面的案例我们分析日志信息,聚合会创建2个关于日志数据的分组,一个包含错误信息,一个包含警告信息。
响应如下:
{
"took": 9,
"timed_out": false,
"_shards": ...,
"hits": ...,
"aggregations": {
"messages": {
"buckets": {
"errors": {
"doc_count": 1
},
"warnings": {
"doc_count": 2
}
}
}
}
}
filters
字段可以作为filters过滤数组, 如下:
GET logs/_search
{
"size": 0,
"aggs" : {
"messages" : {
"filters" : {
"filters" : [
{ "match" : { "body" : "error" }},
{ "match" : { "body" : "warning" }}
]
}
}
}
}
过滤数组返回的分组和请求一致. 响应如下:
{
"took": 4,
"timed_out": false,
"_shards": ...,
"hits": ...,
"aggregations": {
"messages": {
"buckets": [
{
"doc_count": 1
},
{
"doc_count": 2
}
]
}
}
}
other_bucket 属性可以在响应中添加一个分组,又来收集所有没有任何匹配的文档:
取值 | 说明 |
---|---|
false | 不做其他分组操纵 |
true | 返回其他分组,如果有命名过滤聚合,呢么默认这个分组会被命名为_other_ ,如果是匿名聚合将作为做后一个分组返回 |
other_bucket_key 参数可以用来为其他分组命名而不是默认的_other_
. 设置这个属性需要设置_bucket
参数为 true
.
下面是一个其他分组命名为other_messages
的案例。
PUT logs/_doc/4?refresh
{
"body": "info: user Bob logged out"
}
GET logs/_search
{
"size": 0,
"aggs" : {
"messages" : {
"filters" : {
"other_bucket_key": "other_messages",
"filters" : {
"errors" : { "match" : { "body" : "error" }},
"warnings" : { "match" : { "body" : "warning" }}
}
}
}
}
}
响应如下
{
"took": 3,
"timed_out": false,
"_shards": ...,
"hits": ...,
"aggregations": {
"messages": {
"buckets": {
"errors": {
"doc_count": 1
},
"warnings": {
"doc_count": 2
},
"other_messages": {
"doc_count": 1
}
}
}
}
}
Global Aggregation是一个无视检索条件包含所有文档的单分组聚合。聚合的上下文只受检索的索引限制不受检索条件限制。
注意:
Global aggregators 只能作为最顶级的聚合使用,把Global Aggregation潜入其他分组是没有意义的。
例如:
POST /sales/_search?size=0
{
"query" : {
"match" : { "type" : "t-shirt" }
},
"aggs" : {
"all_products" : {
"global" : {}, #global aggregation有一个空的请求体
"aggs" : { #子聚合包含在global aggregation中
"avg_price" : { "avg" : { "field" : "price" } }
}
},
"t_shirts": { "avg" : { "field" : "price" } }
}
}
上面的案例展示了怎么在无视查询条件下对所有的文档执行聚合操作(例如avg_price
),在我们的案例中我们计算所有产品的平均价格而不是t_shirts
结果如下
{
...
"aggregations" : {
"all_products" : {
"doc_count" : 7,
"avg_price" : {
"value" : 140.71428571428572
}
},
"t_shirts": {
"value" : 128.33333333333334
}
}
}
Missing Aggregation是一个对于文档集中对所有确实字段值或者字段值被设置为null
的文档创建一个分组的单分组聚合。这个聚合通常和其他字段数据分组聚合一起使用,例如范围聚合,返回由于缺少字段值无法放入任何分组的文档集。
例如
POST /sales/_search?size=0
{
"aggs" : {
"products_without_a_price" : {
"missing" : { "field" : "price" }
}
}
}
上面的案例中,我们可以得到所有没有价格的产品
响应如下:
{
...
"aggregations" : {
"products_without_a_price" : {
"doc_count" : 00
}
}
}