ElasticSearch日期转换为Java LocalDateTime失败

时间:2019-02-21 15:53:23

标签: java spring-boot elasticsearch spring-data-jpa

我有一个微服务,该服务从ElasticSearch索引中读取数据并进行处理。该索引具有日期字段,并且我无法将日期字段数据加载到文档实体中。这是我正在尝试实现的快照。

索引

"date_created": {
  "type": "date"
}

将日期存储为

"date_created": "2015-07-02T14:56:51.000Z"

我的实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(indexName = "account", type = "doc")
public class Account implements Serializable {

...

    @JsonProperty("date_created")
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ")
    @JsonSerialize(using = LocalDateTimeSerializer.class)
    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    private LocalDateTime dateCreated;

...

}

在运行时从ElasticSearch存储库中获取记录时出现以下错误

nested exception is org.springframework.data.elasticsearch.ElasticsearchException: failed to map source ...
java.time.format.DateTimeParseException: Text '2002-08-05T04:00:00.000Z' could not be parsed, unparsed text found at index 23

有没有办法可以解决这个问题?我将尝试按以下方式更改索引定义和JsonFormat,但不确定是否可以使用。我事先询问,因为我将花一些时间来实施索引更改。

索引更改,我稍后再试。

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

JsonFormat更改

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS")

非常感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

我如上所述重新创建了索引。但是,创建索引后,logstash开始无法将数据泵入索引中。在流内修复数据可能会花费很大。因此,我恢复了原始索引。

什么真正解决了我的问题?我对@JsonFormat的模式进行了微小的更改,并且成功了。

之前

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ")

之后

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")

因此,基本上,返回的日期中的“ Z”是字符而不是日期格式程序。使用单引号,我告诉格式化程序将其视为字符而不是格式字符串。

希望这可以解决其他人的困惑。

答案 1 :(得分:0)

我遇到了同样的问题:日期值中的'Z'被视为字符,因此日期解析失败。我的解决方案却有些不同:

@Field(type = FieldType.Date, format = DateFormat.custom, pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'")
private LocalDateTime dateField;

如果我们不想一次又一次地在不同的字段上重复该模式,则可以尝试集中于转换逻辑。 Spring Data Elastic Search提供了自定义转换功能,请查看here以获取示例。我们可以编写一个从String到Date的转换器,然后将日期模式放在那。