如何将 Instant/JodaDateTimeConverter 与 Spring 数据一起使用 Elasticsearch

How to use Instant/JodaDateTimeConverter with Spring Data Elasticsearch

有一个 class JodaDateTimeConverter,它显然是设计用来存储带有 Spring Data Elasticsearch 的 Instant 字段。但是我该如何使用它呢?我还没有找到任何例子。

正在尝试将 Instant 用作日期字段:

@Field(index = FieldIndex.analyzed, type = Date)
private Instant someTime;

给我这个例外:

Caused by: java.lang.IllegalArgumentException: unknown property [epochSecond]
    at org.elasticsearch.index.mapper.core.DateFieldMapper.innerParseCreateField(DateFieldMapper.java:520)
    at org.elasticsearch.index.mapper.core.NumberFieldMapper.parseCreateField(NumberFieldMapper.java:241)
    at org.elasticsearch.index.mapper.FieldMapper.parse(FieldMapper.java:321)
    ... 21 more

考虑一下,在使用存储库时...

@Document(indexName = "ESINDEX", type = "TYPE", shards = 5)
public class YourClass implements java.io.Serializable {

@Id
private String url;

.
. 
.

@Field(type = FieldType.Date, format = DateFormat.date_optional_time)
private Date created;
@Field(type = FieldType.Date, format = DateFormat.date_optional_time)
private Date updated;

.
.
}

我找到了解决此问题的方法,方法是使用 https://github.com/spring-projects/spring-data-elasticsearch/wiki/Custom-ObjectMapper 中所述的自定义对象映射器并将 Jackson 配置为将 Instants 序列化为时间戳:

public class CustomEntityMapper implements EntityMapper {

private ObjectMapper objectMapper;

public CustomEntityMapper(ObjectMapper objectMapper) {
    this.objectMapper = objectMapper;
    objectMapper.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false);
    objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true);
    objectMapper.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS, false);
}

@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);
}

}

Spring配置代码:

    @Bean
    @Autowired
    public ElasticsearchTemplate elasticsearchTemplate(Client client) {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new JavaTimeModule());
        return new ElasticsearchTemplate(client, new CustomEntityMapper(objectMapper));
    }

如果您使用的是 es 生成的 ID,则使用此方法会中断自动 ID 解析。在这里查看我的 post -