日期字段类型

在 UDB-SX 中,日期可以表示为以下形式之一:

  • 自纪元(纪元时间必须为非负值)以来的毫秒数(长整型值)。日期在内部以此形式存储。

  • 格式化的字符串。

  • 自纪元(纪元时间必须为非负值)以来的秒数(整型值)。

为了表示日期范围,设有日期范围字段类型

示例

创建一个包含日期字段和两种日期格式的映射:

PUT testindex
{
  "mappings" : {
    "properties" :  {
      "release_date" : {
        "type" : "date",
        "format" : "strict_date_optional_time||epoch_millis"
      }
    }
  }
}

参数

下表列出了日期字段类型接受的参数。所有参数均为可选。

参数 描述
boost 一个浮点值,用于指定此字段对相关性评分的影响力。大于 1.0 的值会增加字段的相关性。介于 0.0 和 1.0 之间的值会降低字段的相关性。默认值为 1.0。
doc_values 一个布尔值,指定是否应将字段存储在磁盘上,以便用于聚合、排序或脚本操作。默认值为 false
format 用于解析日期的格式。默认值为 strict_date_time_no_millis||strict_date_optional_time||epoch_millis
ignore_malformed 一个布尔值,指定是否忽略格式错误的值且不抛出异常。默认值为 false
index 一个布尔值,指定字段是否应可被搜索。默认值为 true
locale 表示日期的特定区域和语言方式。默认值为 ROOT(一个与地区和语言无关的区域设置)。
meta 接受此字段的元数据。
null_value 用于替代 null 的值。必须与字段类型相同。如果未指定此参数,当字段值为 null 时,该字段被视为缺失。默认值为 null
store 一个布尔值,指定是否应存储字段值,并且可以从 _source 字段中单独检索。默认值为 false

格式

UDB-SX 提供了内置的日期格式,但您也可以创建自己的自定义格式。您可以指定多个日期格式,用 || 分隔。

默认格式

您可以选择使用实验性的默认日期格式 strict_date_time_no_millis||strict_date_optional_time||epoch_millis。要使用此实验性默认格式,请将功能标志 opensearch.experimental.optimization.datetime_formatter_caching.enabled 设置为 true

内置格式

大多数日期格式都有对应的 strict_ 版本。当格式以 strict_ 开头时,日期必须符合格式中指定的精确位数。例如,如果格式设置为 strict_year_month_day ("yyyy-MM-dd"),月份和日期都必须是两位数。因此,"2020-06-09" 有效,而 "2020-6-9" 无效。

纪元定义为 1970 年 1 月 1 日 00:00:00 UTC。

y: 年
Y: 基于周的年份
M: 月
w: 一年中的序数周次,从 01 到 53
d: 日
D: 一年中的序数日,从 001 到 365(闰年为 366)
e: 一周中的序数日,从 1(星期一)到 7(星期日)
H: 小时,从 0 到 23
m: 分钟
s: 秒
S: 秒的小数部分
Z: 时区偏移量(例如,+0400;-0400;-04:00)

数字日期格式

格式名称和描述 示例
epoch_millis
自纪元以来的毫秒数。最小值为 -263。最大值为 263 − 1。
1553391286000
epoch_second
自纪元以来的秒数。最小值为 -263 ÷ 1000。最大值为 (263 − 1) ÷ 1000。
1553391286

基本日期格式

基本日期格式的组成部分之间没有分隔符。例如,”20190323”。

格式名称和描述 模式和示例
日期
basic_date_time
T 分隔的基本日期和时间。
"yyyyMMddTHHmmss.SSSZ"
"20190323T213446.123-04:00"
basic_date_time_no_millis
不带毫秒的基本日期和时间,由 T 分隔。
"yyyyMMddTHHmmssZ"
"20190323T213446-04:00"
basic_date
包含四位年份、两位月份和两位日期的日期。
"yyyyMMdd"
"20190323"
时间
basic_time
包含两位小时、两位分钟、两位秒、三位毫秒和时区偏移量的时间。
"HHmmss.SSSZ"
"213446.123-04:00"
basic_time_no_millis
不带毫秒的基本时间。
"HHmmssZ"
"213446-04:00"
T 时间
basic_t_time
T 开头的基本时间。
"THHmmss.SSSZ"
"T213446.123-04:00"
basic_t_time_no_millis
T 开头且不带毫秒的基本时间。
"THHmmssZ"
"T213446-04:00"
序数日期
basic_ordinal_date_time
完整的序数日期和时间。
"yyyyDDDTHHmmss.SSSZ"
"2019082T213446.123-04:00"
basic_ordinal_date_time_no_millis
不带毫秒的完整序数日期和时间。
"yyyyDDDTHHmmssZ"
"2019082T213446-04:00"
basic_ordinal_date
包含四位年份和三位年份中序数日的日期。
"yyyyDDD"
"2019082"
基于周的日期
basic_week_date_time
strict_basic_week_date_time
T 分隔的完整基于周的日期和时间。
"YYYYWwweTHHmmss.SSSZ"
"2019W126213446.123-04:00"
basic_week_date_time_no_millis
strict_basic_week_date_time_no_millis
不带毫秒的基本基于周年的日期和时间,由 T 分隔。
"YYYYWwweTHHmmssZ"
"2019W126213446-04:00"
basic_week_date
strict_basic_week_date
包含四位基于周的年份、两位年份中序数周和一位周中序数日的完整基于周的日期,由 W 分隔。
"YYYYWwwe"
"2019W126"

完整日期格式

完整日期格式的组成部分之间使用 - 分隔符分隔日期,使用 : 分隔符分隔时间。例如,"2019-03-23T21:34"

格式名称和描述 模式和示例
日期
date_optional_time
strict_date_optional_time
通用的完整日期和时间。年份必填。月份、日期和时间可选。时间通过 T 与日期分隔。
多种模式。
"2019-03-23T21:34:46.123456789-04:00"
"2019-03-23T21:34:46"
"2019-03-23T21:34"
"2019"
strict_date_optional_time_nanos
通用的完整日期和时间。年份必填。月份、日期和时间可选。如果指定了时间,则必须包含小时、分钟和秒,但秒的小数部分可选。秒的小数部分长度为一到九位,具有纳秒精度。时间通过 T 与日期分隔。
多种模式。
"2019-03-23T21:34:46.123456789-04:00"
"2019-03-23T21:34:46"
"2019"
date_time
strict_date_time
T 分隔的完整日期和时间。
"yyyy-MM-ddTHH:mm:ss.SSSZ"
"2019-03-23T21:34:46.123-04:00"
date_time_no_millis
strict_date_time_no_millis
不带毫秒的完整日期和时间,由 T 分隔。
"yyyy-MM-dd'T'HH:mm:ssZ"
"2019-03-23T21:34:46-04:00"
date_hour_minute_second_fraction
strict_date_hour_minute_second_fraction
完整的日期、两位小时、两位分钟、两位秒以及一到九位秒的小数部分,由 T 分隔。
"yyyy-MM-ddTHH:mm:ss.SSSSSSSSS"
"2019-03-23T21:34:46.123456789"
"2019-03-23T21:34:46.1"
date_hour_minute_second_millis
strict_date_hour_minute_second_millis
完整的日期、两位小时、两位分钟、两位秒以及三位毫秒,由 T 分隔。
"yyyy-MM-ddTHH:mm:ss.SSS"
"2019-03-23T21:34:46.123"
date_hour_minute_second
strict_date_hour_minute_second
完整的日期、两位小时、两位分钟和两位秒,由 T 分隔。
"yyyy-MM-ddTHH:mm:ss"
"2019-03-23T21:34:46"
date_hour_minute
strict_date_hour_minute
完整的日期、两位小时和两位分钟。
"yyyy-MM-ddTHH:mm"
"2019-03-23T21:34"
date_hour
strict_date_hour
完整的日期和两位小时,由 T 分隔。
"yyyy-MM-ddTHH"
"2019-03-23T21"
date
strict_date
四位年份、两位月份和两位日期。
"yyyy-MM-dd"
"2019-03-23"
year_month_day
strict_year_month_day
四位年份、两位月份和两位日期。
"yyyy-MM-dd"
"2019-03-23"
year_month
strict_year_month
四位年份和两位月份。
"yyyy-MM"
"2019-03"
year
strict_year
四位年份。
"yyyy"
"2019"
rfc3339_lenient
兼容 RFC3339 的 DateTimeFormatter,比其他完整日期宽松格式(如 strict_date_optional_time)快得多。
"YYYY"
"2019"
"YYYY-MM"
"2019-03"
"YYYY-MM-DD"
"2019-03-23"
"YYYY-MM-DDThh:mmTZD"
"2019-03-23T21:34Z"
"YYYY-MM-DDThh:mm:ssTZD"
"2019-03-23T21:34:46Z"
"YYYY-MM-DDThh:mm:ss.sTZD"
"2019-03-23T21:34:46.123456789-04:00"
"YYYY-MM-DDThh:mm:ss,sTZD"
"2019-03-23T21:34:46,123456789-04:00"
时间
time
strict_time
两位小时、两位分钟、两位秒、一到九位秒的小数部分和时区偏移量。
"HH:mm:ss.SSSSSSSSSZ"
"21:34:46.123456789-04:00"
"21:34:46.1-04:00"
time_no_millis
strict_time_no_millis
两位小时、两位分钟、两位秒和时区偏移量。
"HH:mm:ssZ"
"21:34:46-04:00"
hour_minute_second_fraction
strict_hour_minute_second_fraction
两位小时、两位分钟、两位秒以及一到九位秒的小数部分。
"HH:mm:ss.SSSSSSSSS"
"21:34:46.1"
"21:34:46.123456789"
hour_minute_second_millis
strict_hour_minute_second_millis
两位小时、两位分钟、两位秒和三位毫秒。
"HH:mm:ss.SSS"
"21:34:46.123"
hour_minute_second
strict_hour_minute_second
两位小时、两位分钟和两位秒。
"HH:mm:ss"
"21:34:46"
hour_minute
strict_hour_minute
两位小时和两位分钟。
"HH:mm"
"21:34"
hour
strict_hour
两位小时。
"HH"
"21"
T 时间
t_time
strict_t_time
T 开头的两位小时、两位分钟、两位秒、一到九位秒的小数部分和时区偏移量。
"THH:mm:ss.SSSSSSSSSZ"
"T21:34:46.123456789-04:00"
"T21:34:46.1-04:00"
t_time_no_millis
strict_t_time_no_millis
T 开头的两位小时、两位分钟、两位秒和时区偏移量。
"THH:mm:ssZ"
"T21:34:46-04:00"
序数日期
ordinal_date_time
strict_ordinal_date_time
T 分隔的完整序数日期和时间。
"yyyy-DDDTHH:mm:ss.SSSZ"
"2019-082T21:34:46.123-04:00"
ordinal_date_time_no_millis
strict_ordinal_date_time_no_millis
不带毫秒的完整序数日期和时间,由 T 分隔。
"yyyy-DDDTHH:mm:ssZ"
"2019-082T21:34:46-04:00"
ordinal_date
strict_ordinal_date
包含四位年份和三位年份中序数日的完整序数日期。
"yyyy-DDD"
"2019-082"
基于周的日期
week_date_time
strict_week_date_time
T 分隔的完整基于周的日期和时间。周日期包含四位基于周的年份、两位年份中序数周和一位周中序数日。时间包含两位小时、两位分钟、两位秒、一到九位秒的小数部分和时区偏移量。
"YYYY-Www-eTHH:mm:ss.SSSSSSSSSZ"
"2019-W12-6T21:34:46.1-04:00"
"2019-W12-6T21:34:46.123456789-04:00"
week_date_time_no_millis
strict_week_date_time_no_millis
不带毫秒的完整基于周的日期和时间,由 T 分隔。周日期包含四位基于周的年份、两位年份中序数周和一位周中序数日。时间包含两位小时、两位分钟、两位秒和时区偏移量。
"YYYY-Www-eTHH:mm:ssZ"
"2019-W12-6T21:34:46-04:00"
week_date
strict_week_date
包含四位基于周的年份、两位年份中序数周和一位周中序数日的完整基于周的日期。
"YYYY-Www-e"
"2019-W12-6"
weekyear_week_day
strict_weekyear_week_day
四位基于周的年份、两位年份中序数周和一位周中日。
"YYYY-'W'ww-e"
"2019-W12-6"
weekyear_week
strict_weekyear_week
四位基于周的年份和两位年份中序数周。
"YYYY-Www"
"2019-W12"
weekyear
strict_weekyear
四位基于周的年份。
"YYYY"
"2019"

自定义格式

您可以为日期字段创建自定义格式。例如,以下请求指定了常见的 "MM/dd/yyyy" 格式:

PUT testindex
{
  "mappings" : {
    "properties" :  {
      "release_date" : {
        "type" : "date",
        "format" : "MM/dd/yyyy"
      }
    }
  }
}

索引一个包含日期的文档:

PUT testindex/_doc/21 
{
  "release_date" : "03/21/2019"
}

搜索确切日期时,请以相同格式提供该日期:

GET testindex/_search
{
  "query" : {
    "match": {
      "release_date" : {
        "query": "03/21/2019"
      }
    }
  }
}

范围查询默认使用字段映射的格式。您也可以通过提供 format 参数,以不同格式指定日期范围:

GET testindex/_search
{
  "query": {
    "range": {
      "release_date": {
        "gte": "2019-01-01",
        "lte": "2019-12-31",
        "format": "yyyy-MM-dd"
      }
    }
  }
}

日期运算

日期字段类型支持在查询中使用日期运算来指定时间段。例如,范围查询中的 gtgteltlte 参数,以及日期范围聚合中的 fromto 参数都接受日期运算表达式。

一个日期运算表达式包含一个固定日期,后面可选地跟一个或多个数学表达式。固定日期可以是 now(自纪元以来的当前日期和时间,以毫秒计)或一个以 || 结尾的字符串,用于指定日期(例如,2022-05-18||)。日期必须采用默认格式(默认为 strict_date_time_no_millis||strict_date_optional_time||epoch_millis)。

如果在字段映射中指定了多种日期格式,UDB-SX 会使用第一种格式将自纪元以来的毫秒数值转换为字符串。
如果字段的字段映射不包含格式,UDB-SX 会使用 strict_date_optional_time 格式将纪元值转换为字符串。

日期运算支持以下数学运算符。

运算符 描述 示例
+ 加法 +1M:加 1 个月。
- 减法 -1y:减 1 年。
/ 向下舍入 /h:舍入到小时的开始。

日期运算支持以下时间单位:

y:年
M:月
w:周
d:日
hH:小时
m:分钟
s:秒

表达式示例

以下示例表达式说明了日期运算的用法:

  • now+1M:自纪元以来的当前日期和时间(毫秒),加上 1 个月。

  • 2022-05-18||/M2022年5月18日,舍入到该月的开始。解析为 2022-05-01

  • 2022-05-18T15:23||/h2022年5月18日 15:23,舍入到该小时的开始。解析为 2022-05-18T15

  • 2022-05-18T15:23:17.789||+2M-1d/d2022年5月18日 15:23:17.789 加上 2 个月减去 1 天,再舍入到该天的开始。解析为 2022-07-17

在范围查询中使用日期运算

以下示例说明了如何在范围查询中使用日期运算。

设置一个索引,将 release_date 映射为 date 类型:

PUT testindex 
{
  "mappings" : {
    "properties" :  {
      "release_date" : {
        "type" : "date"
      }
    }
  }
}

向索引中索引两个文档:

PUT testindex/_doc/1
{
  "release_date": "2022-09-14"
}
PUT testindex/_doc/2
{
  "release_date": "2022-11-15"
}

以下查询搜索 release_date2022年9月14日 前后 2 个月零 1 天内的文档。范围的下边界被舍入到 2022年9月14日 的开始:

GET testindex/_search
{
  "query": {
    "range": {
      "release_date": {
        "gte": "2022-09-14T15:23||/d",
        "lte": "2022-09-14||+2M+1d"
      }
    }
  }
}

响应包含两个文档:

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "testindex",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "release_date" : "2022-11-14"
        }
      },
      {
        "_index" : "testindex",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "release_date" : "2022-09-14"
        }
      }
    ]
  }
}