我正在尝试索引包含时区日期的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 [无法解析[startDate]];嵌套: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
不成功吗?这些格式不一样吗?
更新:我对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年开始的,但问题依然存在。看起来还不支持纳秒级精度。
我不确定我的“修复”是否适合任何人看到这个问题。但情况越来越糟。我无法解析任何以0结尾的日期。所以yyyy-MM-dd'T'HH:mm:00
和yyyy-MM-dd'T'HH:00
会失败,但yyyy-MM-dd'T'HH:mm:01
或yyyy-MM-dd'T'HH:01
会成功。我销毁了整个elasticsearch数据库并升级到6.1并重新编制了我的所有数据。我不再看到这个问题了。