我正在使用Spring Data对Elasticsearch的支持。这是时间戳字段映射:
@Field(type = FieldType.Date, index = FieldIndex.not_analyzed, store = true, format = DateFormat.custom, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZZ") @JsonFormat(shape = JsonFormat.Shape.STRING, pattern ="yyyy-MM-dd'T'HH:mm:ss.SSSZZ") private LocalDateTime timestamp;
这导致Elasticsearch中的字段映射如下:
"timestamp":{"type":"date","store":true,"format":"yyyy-MM-dd'T'HH:mm:ss.SSSZZ"}
当我使用java.util.Date时,一切正常。但是,当我如上所述切换到java.time.LocalDateTime时,发送到Elasticsearch的文档导致异常。这是文档(为简洁起见,时间戳字段):
"timestamp": { "hour":7, "minute":56, "second":9, "nano":147000000, "year":2017, "month":"FEBRUARY", "dayOfMonth":13, "dayOfWeek":"MONDAY", "dayOfYear":44, "monthValue":2, "chronology": { "id":"ISO", "calendarType": "iso8601" } }
和例外:
MapperParsingException[failed to parse [timestamp]]; nested: IllegalArgumentException[unknown property [hour]]; (...) Caused by: java.lang.IllegalArgumentException: unknown property [hour]
似乎在对文档进行json转换时,此处的模式已被忽略。有任何提示吗?也许您可能知道如何在Spring Data中使用“内置” _timestamp字段?
检查https://github.com/spring-projects/spring-data-elasticsearch/wiki/Custom- ObjectMapper添加JavaTimeModule到您的中ObjectMapper。
JavaTimeModule
ObjectMapper
@Configuration public class ElasticSearchConfiguration { @Bean public ElasticsearchTemplate elasticsearchTemplate(Client client) { return new ElasticsearchTemplate(client, new CustomEntityMapper()); } public static class CustomEntityMapper implements EntityMapper { private final ObjectMapper objectMapper; public CustomEntityMapper() { objectMapper = new ObjectMapper(); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); objectMapper.registerModule(new CustomGeoModule()); objectMapper.registerModule(new JavaTimeModule()); } @Override public String mapToString(Object object) throws IOException { return objectMapper.writeValueAsString(object); } @Override public <T> T mapToObject(String source, Class<T> clazz) throws IOException { return objectMapper.readValue(source, clazz); } } }