Elasticsearch教程|【Elasticsearch教程11】Mapping字段类型之日期时间date date_nanos


Elasticsearch Mapping字段类型之日期时间date date_nanos

  • 一、日期格式
    • 1.1 简介
    • 1.2 什么是epoch_millis?
    • 1.3 什么是strict_date_optional_time?
  • 二、实验
    • 2.1 测试date类型
    • 2.2 测试错误的格式:`yyyy-MM-ddTHH:mm:s`
    • 2.3 测试错误的格式:`yyyy-MM-dd HH:mm:ss`
  • 三、混合日期格式
  • 四、date_nanos,支持纳秒
  • 五、性能优化

一、日期格式 1.1 简介 JSON没有date类型,但我们可以把以下类型作为日期时间存入ES。
类型 说明
字符串 日期格式的字符串,如"2015-01-01"或"2015/01/01 12:10:30"
长整型 从开始纪元(1970-01-01 00:00:00 UTC)开始的毫秒数
整型 从开始纪元(1970-01-01 00:00:00 UTC)开始的秒数
上面的UTC(Universal Time Coordinated) 叫做世界统一时间,中国大陆和 UTC 的时差是 + 8 ,也就是 UTC+8。在ES内部,时间以毫秒数(long型)存储,而展现有多种format格式。
date的格式可以被指定的,如果没有指定,默认“strict_date_optional_time || epoch_millis”
strict_date_optional_time或者epoch_millis)。
1.2 什么是epoch_millis?
  • epoch_millis就是从开始纪元(1970-01-01 00:00:00 UTC)开始的毫秒数(long型)
  • 1970以前的时间也可以, 值是负数。
如下图,2020/8/31 14:57:56是常用的日期格式,它距离1970-01-01 00:00:00 有 1598857076000豪秒。所以可以用1598857076000表示2020/8/31 14:57:56
Elasticsearch教程|【Elasticsearch教程11】Mapping字段类型之日期时间date date_nanos
文章图片

1.3 什么是strict_date_optional_time? strict_date_optional_timedate_optional_time的严格级别,这个严格指的是年份、月份、天必须分别以4位、2位、2位表示,不足两位的话第一位需用0补齐。常见格式如下:
  • yyyy
  • yyyyMM
  • yyyyMMdd
  • yyyyMMddHHmmss
  • yyyy-MM
  • yyyy-MM-dd
  • yyyy-MM-ddTHH:mm:ss dd后面有个T
  • yyyy-MM-ddTHH:mm:ss.SSS
  • yyyy-MM-ddTHH:mm:ss.SSSZ
工作常见到是yyyy-MM-dd HH:mm:ss,但ES默认不支持这格式,我们可以在format里自定义支持它。上面最后一个里大写的"Z"表示时区。
二、实验 2.1 测试date类型 新增一个索引,设置birthday是date格式。
#ES7去掉了type,所以mappings下面一层不用写“_doc” PUT /test_date_index { "mappings":{ "properties":{ "birthday":{ "type":"date" } } } }

测试存入时间格式
PUT test_date_index/_doc/0 { "birthday":"2020-08" }PUT test_date_index/_doc/1 { "birthday":"2020-08-31" }PUT test_date_index/_doc/2 { "birthday":"2020-08-31T14:32" }PUT test_date_index/_doc/3 { "birthday":"2020-08-31T14:32:11" }PUT test_date_index/_doc/4 { "birthday":"1598857076000" }#1970以前的时间也可以, 值是负数 PUT test_date_index/_doc/5 { "birthday":"1955-08-31T14:32:11" }

2.2 测试错误的格式:yyyy-MM-ddTHH:mm:s 因为秒只有1位,左侧没有补0,所以不是合法格式。
#插入yyyy-MM-ddTHH:mm:s格式 PUT test_date_index/_doc/3 { "bithday":"2020-08-31T14:32:1" }结果报错: "type" : "illegal_argument_exception", "reason" : "failed to parse date field [2020-08-31T14:32:1] with format [strict_date_optional_time||epoch_millis]",

2.3 测试错误的格式:yyyy-MM-dd HH:mm:ss
#插入yyyy-MM-dd HH:mm:ss格式 PUT /test_date_index/_doc/3 { "birthday": "2020-03-01 16:29:41" }结果报错: "caused_by": { "type": "illegal_argument_exception", "reason": "Invalid format: \"2020-03-01 16:29:41\" is malformed at \" 16:29:41\"" }

#插入 yyyy-MM-ddTHH:mm:ss格式,ES返回成功 PUT /test_date_index/_doc/4 { "birthday": "2020-03-01T16:29:41" }

三、混合日期格式 date类型,还支持一个参数format,它让我们可以自己定制化日期格式。
比如format配置了格式A||格式B||格式C,插入一个值后,会从左往右匹配,直到有一个格式匹配上。
举例:你想一个字段同时支持yyyy-MM-dd HH:mm:ssyyyy-MM-ddepoch_millis这3种格式,没有问题,只需在format上设置这3个格式,它们在ES内部都是按照long类型存储的。
#重建索引 PUT /test_date_index { "mappings":{ "properties":{ "birthday":{ "type":"date", "format":"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" } } } }PUT /test_date_index/_doc/1 { "birthday": "2020-03-01 16:29:41" }PUT /test_date_index/_doc/2 { "birthday": "2020-02-29" }#2020/03/01 17:44:09的毫秒级时间戳 PUT /test_date_index/_doc/3 { "birthday": 1583055849000 }

四、date_nanos,支持纳秒 date类型支持到毫秒,如果特殊情况下用到纳秒得用date_nanos类型。
#创建一个index,其date字段是date_nanos类型,支持纳秒 PUT my_index?include_type_name=true { "mappings": { "_doc": { "properties": { "date": { "type": "date_nanos" } } } } }#和普通的date类型一样,可以存strict_date_optional_time||epoch_millis这些格式的 #不过在es内部是存的长整型是纳秒单位的 PUT my_index/_doc/1 { "date": "2015-01-01" } #存一个具体到纳秒的值 PUT my_index/_doc/2 { "date": "2015-01-01T12:10:30.123456789Z" } #存的是整型,说明是秒,换成日期就是2015/1/1 8:0:0 #但是在es内部,会以纳秒为单位的long类型存储 PUT my_index/_doc/3 { "date": 1420070400 } GET my_index/_search { "sort": { "date": "asc"} }

五、性能优化
  • 如果不在日期时间字段上做排序、聚合和script脚本操作,可以设置doc_value为false。
  • 如果不在日期时间字段上做检索,只是做展示用,可以设置index为false。
【Elasticsearch教程|【Elasticsearch教程11】Mapping字段类型之日期时间date date_nanos】如果本文对您有帮助,就给亚瑟王点个赞吧

    推荐阅读