格式错误的日期错误将数据索引到Elasticsearch中

时间:2017-12-14 18:57:17

标签: java elasticsearch gson datetime-format datetime-parsing

我正在尝试为elasticsearch中的数据编制索引,其中包含带时区的日期。

我的日期映射是:

"date": {
    "type": "date",
    "format": "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
}

我使用以下代码索引数据:

client.prepareIndex(INDEX, TYPE, id))
        .setSource(gson.toJson(object), XContentType.JSON)
        .setRefreshPolicy(RefreshPolicy.IMMEDIATE)
        .get();

我已经创建了我自己的ZonedDateTime适配器,如下所示:

public class ZonedDateTimeAdapter implements JsonSerializer<ZonedDateTime> {

    public JsonElement serialize(ZonedDateTime date, Type typeOfSrc, JsonSerializationContext context) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
        return new JsonPrimitive(date.format(formatter));
    }

}

结果日期类似于2005-01-01T13:35:50.596-0500。对我而言似乎符合yyyy-MM-dd'T'HH:mm:ss.SSSZ的格式。但是我收到错误声明:

  

线程“main”中的异常MapperParsingException [无法解析   [开始日期]];嵌套:IllegalArgumentException [格式无效:   “2005-01-01T13:35:50.596-0500”格式错误为“.596-0500”]

有趣的是,如果我将ZonedDateTimeAdapter中的格式更改为读取yyyy-MM-dd'T'HH:mm:ss.000Z(强制第二个分数始终为000),我得到的结果日期为2005-01-01T13:31:06.000-0500。具有此日期的对象已成功编入索引到elasticsearch。

您知道为什么2005-01-01T13:31:06.000-0500索引成功但2005-01-01T13:35:50.596-0500没有成功吗?这些格式不一样吗?

2 个答案:

答案 0 :(得分:2)

更新:我对ES 5.2进行了快速测试,效果很好。

$curl -XPUT localhost:9200/myindex1 -d '
{"mappings": {"type1": {"properties": {"field1": {
    "type": "date", 
    "format": "yyyy-MM-dd'\''T'\''HH:mm:ss.SSSZ"
}}}}}
'

$curl -XPUT localhost:9200/myindex1/type1/id1 -d '
    { "field1":"2005-01-01T13:35:50.000-0500" }
'

$curl -XPUT localhost:9200/myindex1/type1/id2 -d '
    { "field1":"2005-01-01T13:35:50.596-0500" }
'

确认我们有相同的映射:

$curl localhost:9200/myindex1/type1/_mapping
{"myindex1":{"mappings":{"type1":{"properties":
    {"field1":{"type":"date","format":"yyyy-MM-dd'T'HH:mm:ss.SSSZ"}}}}}}

来自this thread on https://discuss.elastic.co

  

目前,Elasticsearch仅限于毫秒精度,请参阅此GH issue

这篇文章是从2015年开始的,但问题依然存在。看起来还不支持纳秒精度。

答案 1 :(得分:0)

我不确定我的“修复”是否适合任何人看到此问题。但情况越来越糟。我无法解析以0结尾的任何日期。因此yyyy-MM-dd'T'HH:mm:00yyyy-MM-dd'T'HH:00会失败,但yyyy-MM-dd'T'HH:mm:01yyyy-MM-dd'T'HH:01会成功。我销毁了整个elasticsearch数据库并升级到6.1并重新编制了我的所有数据。我不再看到这个问题了。