日期范围聚合编辑

一种专门用于日期值的范围聚合。此聚合与普通 范围 聚合的主要区别在于,fromto 值可以用 日期数学 表达式表示,并且还可以指定一个日期格式,通过该格式将返回 fromto 响应字段。请注意,此聚合包含 from 值,但不包含每个范围的 to 值。

示例

response = client.search(
  index: 'sales',
  size: 0,
  body: {
    aggregations: {
      range: {
        date_range: {
          field: 'date',
          format: 'MM-yyyy',
          ranges: [
            {
              to: 'now-10M/M'
            },
            {
              from: 'now-10M/M'
            }
          ]
        }
      }
    }
  }
)
puts response
POST /sales/_search?size=0
{
  "aggs": {
    "range": {
      "date_range": {
        "field": "date",
        "format": "MM-yyyy",
        "ranges": [
          { "to": "now-10M/M" },  
          { "from": "now-10M/M" } 
        ]
      }
    }
  }
}

< 现在减去 10 个月,向下舍入到月份开始。

>= 现在减去 10 个月,向下舍入到月份开始。

在上面的示例中,我们创建了两个范围桶,第一个将“桶装”所有日期早于 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 参数定义了如何处理缺少值的文档。默认情况下,它们将被忽略,但也可以将它们视为具有值。这可以通过添加一组字段名:值映射来完成,以指定每个字段的默认值。

response = client.search(
  index: 'sales',
  size: 0,
  body: {
    aggregations: {
      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'
            }
          ]
        }
      }
    }
  }
)
puts response
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 字段中没有值的文档将被添加到“Older”桶中,就好像它们具有“1976-11-30”的日期值一样。

日期格式/模式编辑

此信息是从 DateTimeFormatter 复制的

所有 ASCII 字母都保留为格式模式字母,定义如下

符号 含义 表示 示例

G

纪元

文本

AD; Anno Domini; A

u

2004; 04

y

纪元年

2004; 04

D

年中的天数

数字

189

M/L

月份

数字/文本

7; 07; Jul; July; J

d

月中的天数

数字

10

Q/q

季度

数字/文本

3; 03; Q3; 3rd quarter

Y

周为基年的年份

1996; 96

w

周为基年的周数

数字

27

W

月中的周数

数字

4

E

星期几

文本

Tue; Tuesday; T

e/c

本地化星期几

数字/文本

2; 02; Tue; Tuesday; T

F

月中的周数

数字

3

a

上午/下午

文本

PM

h

上午/下午的小时(1-12)

数字

12

K

上午/下午的小时(0-11)

数字

0

k

上午/下午的小时(1-24)

数字

0

H

一天中的小时(0-23)

数字

0

m

分钟

数字

30

s

数字

55

S

秒的几分之一

小数

978

A

一天中的毫秒

数字

1234

n

纳秒

数字

987654321

N

一天中的纳秒

数字

1234000000

V

时区 ID

时区 ID

America/Los_Angeles; Z; -08:30

z

时区名称

时区名称

Pacific Standard Time; PST

O

本地化时区偏移量

偏移量-O

GMT+8; GMT+08:00; UTC-08:00;

X

时区偏移量 Z 表示零

偏移量-X

Z; -08; -0830; -08:30; -083015; -08:30:15;

x

时区偏移量

偏移量-x

+0000; -08; -0830; -08:30; -083015; -08:30:15;

Z

时区偏移量

偏移量-Z

+0000; -0800; -08:00;

p

填充下一个

填充修饰符

1

'

文本的转义

分隔符

''

单引号

文字

'

[

可选部分开始

]

可选部分结束

#

保留供将来使用

{

保留供将来使用

}

模式字母的计数决定了格式。

文本
文本样式根据使用的模式字母数量确定。少于 4 个模式字母将使用简短形式。正好 4 个模式字母将使用完整形式。正好 5 个模式字母将使用窄形式。模式字母 Lcq 指定文本样式的独立形式。
数字
如果字母的计数为 1,则使用最少的数字位数输出值,并且不进行填充。否则,数字的计数将用作输出字段的宽度,并根据需要用零填充值。以下模式字母对字母的计数有限制。只能指定一个 cF 字母。最多可以指定两个 dHhKkms 字母。最多可以指定三个 D 字母。
数字/文本
如果模式字母的计数为 3 或更大,则使用上面的文本规则。否则,使用上面的数字规则。
小数
将纳秒字段输出为秒的几分之一。纳秒值有九位数字,因此模式字母的计数从 1 到 9。如果小于 9,则纳秒值将被截断,只输出最重要的数字。
字母的计数决定了填充使用的最小字段宽度。如果字母的计数为 2,则使用简化的两位数形式。对于打印,这将输出最右边的两位数字。对于解析,这将使用 2000 的基值进行解析,从而得到一个介于 2000 到 2099(含)之间的年份。如果字母的计数小于 4(但不是 2),则符号仅在负年份中输出,如 SignStyle.NORMAL。否则,如果填充宽度超过,则输出符号,如 SignStyle.EXCEEDS_PAD
ZoneId
这将输出时区 ID,例如 Europe/Paris。如果字母的计数为 2,则输出时区 ID。任何其他字母计数都会抛出 IllegalArgumentException
时区名称
这将输出时区 ID 的显示名称。如果字母的计数为 1、2 或 3,则输出简短名称。如果字母的计数为 4,则输出完整名称。5 个或更多个字母将抛出 IllegalArgumentException
偏移量 X 和 x
这将根据模式字母的数量格式化偏移量。一个字母只输出小时,例如 +01,除非分钟不为零,在这种情况下,分钟也会输出,例如 +0130。两个字母输出小时和分钟,不带冒号,例如 +0130。三个字母输出小时和分钟,带冒号,例如 +01:30。四个字母输出小时和分钟以及可选的秒,不带冒号,例如 +013015。五个字母输出小时和分钟以及可选的秒,带冒号,例如 +01:30:15。六个或更多个字母将抛出 IllegalArgumentException。模式字母 X(大写)将在要输出的偏移量为零时输出 Z,而模式字母 x(小写)将输出 +00+0000+00:00
偏移量 O
这将根据模式字母的数量格式化本地化偏移量。一个字母输出本地化偏移量的简短形式,即本地化偏移量文本,例如 GMT,带不带前导零的小时,可选的两位数分钟和秒(如果非零),以及冒号,例如 GMT+8。四个字母输出完整形式,即本地化偏移量文本,例如 GMT,带两位数小时和分钟字段,可选的秒字段(如果非零),以及冒号,例如 `GMT+08:00`。任何其他字母计数都会抛出 IllegalArgumentException
偏移量 Z
这将根据模式字母的数量格式化偏移量。一个、两个或三个字母输出小时和分钟,不带冒号,例如 +0130。当偏移量为零时,输出将为 +0000。四个字母输出本地化偏移量的完整形式,等效于偏移量-O 的四个字母。如果偏移量为零,输出将是相应的本地化偏移量文本。五个字母输出小时、分钟,以及可选的秒(如果非零),带冒号。如果偏移量为零,它将输出 Z。六个或更多个字母将抛出 IllegalArgumentException。
可选部分
可选部分标记的工作方式与调用 DateTimeFormatterBuilder.optionalStart()DateTimeFormatterBuilder.optionalEnd() 完全相同。
填充修饰符
修改紧随其后的模式,使其用空格填充。填充宽度由模式字母的数量决定。这与调用 DateTimeFormatterBuilder.padNext(int) 相同。

例如,ppH 将输出左侧用空格填充到宽度为 2 的一天中的小时。

任何无法识别的字母都是错误。除 []{}# 和单引号之外的任何非字母字符将直接输出。尽管如此,建议对所有要直接输出的字符使用单引号,以确保将来的更改不会破坏您的应用程序。

日期范围聚合中的时区编辑

可以通过指定 time_zone 参数将日期从另一个时区转换为 UTC。

时区可以指定为 ISO 8601 UTC 偏移量(例如 +01:00 或 -08:00),也可以指定为 TZ 数据库中的时区 ID 之一。

time_zone 参数也应用于日期数学表达式中的舍入。例如,要舍入到 CET 时区的当天开始,您可以执行以下操作

response = client.search(
  index: 'sales',
  size: 0,
  body: {
    aggregations: {
      range: {
        date_range: {
          field: 'date',
          time_zone: 'CET',
          ranges: [
            {
              to: '2016/02/01'
            },
            {
              from: '2016/02/01',
              to: 'now/d'
            },
            {
              from: 'now/d'
            }
          ]
        }
      }
    }
  }
)
puts response
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-01T00:00:00.000+01:00

now/d 将舍入到 CET 时区的当天开始。

带键的响应编辑

keyed 标志设置为 true 将为每个桶关联一个唯一的字符串键,并将范围作为哈希而不是数组返回

response = client.search(
  index: 'sales',
  size: 0,
  body: {
    aggregations: {
      range: {
        date_range: {
          field: 'date',
          format: 'MM-yyy',
          ranges: [
            {
              to: 'now-10M/M'
            },
            {
              from: 'now-10M/M'
            }
          ],
          keyed: true
        }
      }
    }
  }
)
puts response
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
        }
      }
    }
  }
}

也可以为每个范围自定义键

response = client.search(
  index: 'sales',
  size: 0,
  body: {
    aggregations: {
      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
        }
      }
    }
  }
)
puts response
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
        }
      }
    }
  }
}