Link Search Menu Expand Document Documentation Menu

日期字段类型

1.0 版引入

OpenSearch 中的日期可以表示为以下形式之一:

  • 一个长整型值,表示自纪元以来的毫秒数。日期在内部以这种形式存储。
  • 格式化的字符串。
  • 一个整数值,表示自纪元以来的秒数。

为了表示日期范围,存在日期范围字段类型

示例

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

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

参数

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

参数 描述
提升 一个浮点值,指定此字段对相关性得分的权重。高于 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
区域设置 表示日期的区域和语言特定方式。默认值为 ROOT(区域和语言中立的区域设置)。
meta 接受此字段的元数据。
null_value 用于替代 null 的值。必须与字段类型相同。如果未指定此参数,则当其值为 null 时,该字段将被视为缺失。默认值为 null
存储 一个布尔值,指定字段值是否应存储且可与 _source 字段单独检索。默认值为 false

格式

OpenSearch 具有内置日期格式,但您也可以创建自己的自定义格式。您可以指定多个日期格式,用 || 分隔。

默认格式

自 OpenSearch 2.12 起,您可以选择使用实验性默认日期格式: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"<br>"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(自 epoch 以来的当前日期和时间(以毫秒为单位))或以 || 结尾的字符串,用于指定日期(例如,2022-05-18||)。日期必须采用默认格式(默认情况下为 strict_date_time_no_millis||strict_date_optional_time||epoch_millis)。

如果您在字段映射中指定了多种日期格式,OpenSearch 会使用第一种格式将自 epoch 以来的毫秒值转换为字符串。
如果字段的字段映射不包含任何格式,OpenSearch 会使用 strict_date_optional_time 格式将 epoch 值转换为字符串。

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

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

日期数学支持以下时间单位

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

表达式示例

以下示例表达式说明了如何使用日期数学

  • now+1M: 自 epoch 以来的当前日期和时间(以毫秒为单位),加上 1 个月。
  • 2022-05-18||/M: 05/18/2022,四舍五入到月份的开始。解析为 2022-05-01
  • 2022-05-18T15:23||/h: 05/18/202215:23,四舍五入到小时的开始。解析为 2022-05-18T15
  • 2022-05-18T15:23:17.789||+2M-1d/d: 05/18/202215: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_date09/14/2022 前后 2 个月零 1 天内的文档。范围的下限四舍五入到 09/14/2022 的当天开始。

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"
        }
      }
    ]
  }
}