将 Instant、LocalDateTime 和 ZonedDateTime 与 Spring Boot 和 ElasticSearch 结合使用

Swo*_*ish 8 java jackson elasticsearch spring-data spring-boot

我正在使用 Spring Boot 2.1.4 和Spring Data Jest以及 ElasticSearch。我最初使用 Java Date 来获取一些带有以下注释的属性:

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern ="yyyy-MM-dd'T'HH:mm:ss.SSSZZ")
Run Code Online (Sandbox Code Playgroud)

这将保存到 ElasticSearch 中,如下所示:

"creationDate": "2019-04-10T14:49:05.672+0000"
Run Code Online (Sandbox Code Playgroud)

现在,我正在从 Date 迁移到 LocalDateTime 和 ZonedDateTime。当数据现在保存到 ElasticSearch 时,我会保存以下属性:

"creationDate": {
    "dayOfYear": 123,
    "dayOfWeek": "FRIDAY",
    "month": "MAY",
    "dayOfMonth": 3,
    "year": 2019,
    "monthValue": 5,
    "hour": 11,
    "minute": 54,
    "second": 12,
    "nano": 238000000,
    "chronology": {
        "id": "ISO",
        "calendarType": "iso8601"
    }
},
Run Code Online (Sandbox Code Playgroud)

我需要做什么来更改它,以便获得与之前的 LocalDateTime 和 ZonedDateTime 相同的 ElasticSearch 数据格式?

我已经尝试过以下方法:

  1. 自定义对象映射器如下:

    public class CustomEntityMapper implements EntityMapper {
        private final ObjectMapper objectMapper;
    
        public CustomEntityMapper(ObjectMapper objectMapper) {  
            this.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);
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 将以下内容添加到对象映射器:

    objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
    
    Run Code Online (Sandbox Code Playgroud)

任何我出错的地方的帮助或指示将不胜感激。

Swo*_*ish 7

设法让它与 Spring Boot 2.1.4 和 Spring Data Jest 一起工作。这是我所做的:

  1. 域对象示例:

    @Document(indexName = "datetest")
    public class DateTest {
    
        @Id
        private String id;
    
        @Field(type = FieldType.Date, 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", timezone = "UTC")
        private Instant instant = Instant.now();
    
        @Field(type = FieldType.Date, 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 ZonedDateTime zonedDateTime = ZonedDateTime.now();
    
        @Field(type = FieldType.Date, format = DateFormat.custom, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS")
        @JsonFormat(shape = JsonFormat.Shape.STRING, pattern ="yyyy-MM-dd'T'HH:mm:ss.SSS")
        private LocalDateTime localDateTime = LocalDateTime.now();
    
        // getters/setters
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. ElasticSearch/JEST 配置:

    @Configuration
    public class ESConfig {
    
        @Bean
        public EntityMapper getEntityMapper() {
            return new CustomEntityMapper();
        }
    
        @Bean
        @Primary
        public ElasticsearchOperations elasticsearchTemplate(final JestClient jestClient,
                final ElasticsearchConverter elasticsearchConverter,
                final SimpleElasticsearchMappingContext simpleElasticsearchMappingContext, EntityMapper mapper) {
            return new JestElasticsearchTemplate(jestClient, elasticsearchConverter,
                    new DefaultJestResultsMapper(simpleElasticsearchMappingContext, mapper));
        }
    
        public 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);
            }
    
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. ElasticSearch 中的结果:

    ElasticSearch 中的结果屏幕截图

希望这可以帮助。