【elasticsearch】数据类型-时间类型

Date 类型

在你没有定义索引里面字段的类型时,Elasticsearch 会根据你写入的字段的内容动态去判定字段的数据类型,这种自动映射的机制有缺陷,,比如在 Elasticsearch 中没有隐式类型转换,所以在自动映射的时候就会把字段映射为较宽的数据类型。比如你写入一个数字 50,系统就会自动给你映射成 long 类型,而不是 int 。一般企业中用于生产的环境都是使用手工映射,能保证按需创建以节省资源和达到更高的性能。

案例

在kinaba中执行下面内容

POST testdb/_bulk
{"index":{}}
{"title": "文章标题","createTime": "2023-12-13 17:10:20"}

然后查询当前索引 testdb 的mapping,执行 GET testdb,会看到 createTime 的数据类型是 text.
在这里插入图片描述

原因

原因就在于 elasticsearch 对时间类型的格式的要求是绝对严格的。要求必须是一个标准的 UTC 时间类型。上述字段的数据格式如果想要使用,就必须使用yyyy-MM-ddTHH:mm:ssZ格式(其中T个间隔符,Z代表 0 时区),以下均为错误的时间格式(均无法被自动映射器识别为日期时间类型):

yyyy-MM-dd HH:mm:ss
yyyy-MM-dd
时间戳

注意:需要注意的是时间说是必须的时间格式,但是需要通过 手工映射 方式在索引创建之前指定为日期类型,使用自动映射器无法映射为日期类型。

手工设置时间类型

创建索引:

PUT testdb
{
  "mappings": {
    "properties": {
      "createTime": {
        "type": "date"
      }
    }
  }
}
插入数据
POST testdb/_bulk
{"index":{}}
{"title": "文章标题1","createTime": "2023-12-13 17:10:20"}
{"index":{}}
{"title": "文章标题2","createTime": "1702458941"}
{"index":{}}
{"title": "文章标题3","createTime": "2023-12-13T17:10:20Z"}
{"index":{}}
{"title": "文章标题4","createTime": "2023-12-1T17:10:20Z"}
{"index":{}}
{"title": "文章标题5","createTime": "2023-12-13"}

执行结果:

{
  "took" : 196,
  "errors" : true,
  "items" : [
    {
      "index" : {
        "_index" : "testdb",
        "_type" : "_doc",
        "_id" : "cYl4YowBzu9UbbVthrUM",
        "status" : 400,
        "error" : {
          "type" : "mapper_parsing_exception",
          "reason" : "failed to parse field [createTime] of type [date] in document with id 'cYl4YowBzu9UbbVthrUM'. Preview of field's value: '2023-12-13 17:10:20'",
          "caused_by" : {
            "type" : "illegal_argument_exception",
            "reason" : "failed to parse date field [2023-12-13 17:10:20] with format [strict_date_optional_time||epoch_millis]",
            "caused_by" : {
              "type" : "date_time_parse_exception",
              "reason" : "date_time_parse_exception: Failed to parse with all enclosed parsers"
            }
          }
        }
      }
    },
    {
      "index" : {
        "_index" : "testdb",
        "_type" : "_doc",
        "_id" : "col4YowBzu9UbbVthrUM",
        "_version" : 1,
        "result" : "created",
        "_shards" : {
          "total" : 2,
          "successful" : 2,
          "failed" : 0
        },
        "_seq_no" : 0,
        "_primary_term" : 1,
        "status" : 201
      }
    },
    {
      "index" : {
        "_index" : "testdb",
        "_type" : "_doc",
        "_id" : "c4l4YowBzu9UbbVthrUM",
        "_version" : 1,
        "result" : "created",
        "_shards" : {
          "total" : 2,
          "successful" : 2,
          "failed" : 0
        },
        "_seq_no" : 1,
        "_primary_term" : 1,
        "status" : 201
      }
    },
    {
      "index" : {
        "_index" : "testdb",
        "_type" : "_doc",
        "_id" : "dIl4YowBzu9UbbVthrUM",
        "status" : 400,
        "error" : {
          "type" : "mapper_parsing_exception",
          "reason" : "failed to parse field [createTime] of type [date] in document with id 'dIl4YowBzu9UbbVthrUM'. Preview of field's value: '2023-12-1T17:10:20Z'",
          "caused_by" : {
            "type" : "illegal_argument_exception",
            "reason" : "failed to parse date field [2023-12-1T17:10:20Z] with format [strict_date_optional_time||epoch_millis]",
            "caused_by" : {
              "type" : "date_time_parse_exception",
              "reason" : "date_time_parse_exception: Failed to parse with all enclosed parsers"
            }
          }
        }
      }
    },
    {
      "index" : {
        "_index" : "testdb",
        "_type" : "_doc",
        "_id" : "dYl4YowBzu9UbbVthrUM",
        "_version" : 1,
        "result" : "created",
        "_shards" : {
          "total" : 2,
          "successful" : 2,
          "failed" : 0
        },
        "_seq_no" : 2,
        "_primary_term" : 1,
        "status" : 201
      }
    }
  ]
}

结论:

写入成功的是:
	1702458941
	2023-12-13T17:10:20Z
	2023-12-13
写入失败的是:
	2023-12-13 17:10:20
	2023-12-1T17:10:20Z
  • 对于yyyy-MM-dd HH:mm:ss2023-12-1T17:10:20Z,ES 的自动映射器完全无法识别,即便是事先声明日期类型,数据强行写入也会失败。
  • 对于时间戳和yyyy-MM-dd这样的时间格式,ES 自动映射器无法识别,但是如果事先说明了日期类型是可以正常写入的。
  • 对于标准的日期时间类型是可以正常自动识别为日期类型,并且也可以通过手工映射来实现声明字段类型。
  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值