我正在尝试为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
没有成功吗?这些格式不一样吗?
答案 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:00
和yyyy-MM-dd'T'HH:00
会失败,但yyyy-MM-dd'T'HH:mm:01
或yyyy-MM-dd'T'HH:01
会成功。我销毁了整个elasticsearch数据库并升级到6.1并重新编制了我的所有数据。我不再看到这个问题了。