【问题标题】:Spring Data Elasticsearch Repository query define date input parameter formatSpring Data Elasticsearch Repository 查询定义日期输入参数格式
【发布时间】:2019-11-09 13:46:48
【问题描述】:

我正在使用 elasticsearch 6.5.3 和 Spring Boot 2.1.6 和 spring-data-elasticsearch 3.2.0.M1。

我已将 Elasticsearch 配置定义为:

@Bean
    public ElasticsearchOperations elasticsearchTemplate() {
        return new ElasticsearchRestTemplate(client(), new CustomEntityMapper());
    }

    public static class CustomEntityMapper implements EntityMapper {

        private final ObjectMapper objectMapper;

        public CustomEntityMapper() {
            //we use this so that Elasticsearch understands LocalDate and LocalDateTime objects
            objectMapper = new ObjectMapper()
                              .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
                              .enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
                              .disable(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS)
                              .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
                              //MUST be registered BEFORE calling findAndRegisterModules
                              .registerModule(new JavaTimeModule())
                              .registerModule(new Jdk8Module());
            //only autodetect fields and ignore getters and setters for nonexistent fields when serializing/deserializing
            objectMapper.setVisibility(objectMapper.getSerializationConfig().getDefaultVisibilityChecker()
                            .withFieldVisibility(JsonAutoDetect.Visibility.ANY)
                            .withGetterVisibility(JsonAutoDetect.Visibility.NONE)
                            .withSetterVisibility(JsonAutoDetect.Visibility.NONE)
                            .withCreatorVisibility(JsonAutoDetect.Visibility.NONE));
            //load the other available modules as well
            objectMapper.findAndRegisterModules();
        }

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

我有一个存储库,其方法定义为:

List<AccountDateRollSchedule> findAllByNextRollDateTimeLessThanEqual(final LocalDateTime dateTime);

POJO AccountDateRollSchedule 将该字段定义为:

    @Field(type = FieldType.Date, format = DateFormat.date_hour_minute)
    @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm")
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm")
    private LocalDateTime nextRollDateTime;

我看到我的索引正确地按照声明和预期创建了该字段:

"nextRollDateTime": {
          "type": "date",
          "format": "date_hour_minute"
        }

同时查询索引会返回按预期格式化的字段:

"nextRollDateTime" : "2019-06-27T13:34"

我的存储库查询将转换为:

{"query": 
  {"bool" : 
    {"must" : 
      {"range" : 
        {"nextRollDateTime" : 
          {"from" : null, 
           "to" : "?0", 
           "include_lower" : true,
           "include_upper" : true
          }
        }
      }
    }
  }
}

但是将任何 LocalDateTime 输入传递给该方法并不遵守为字段定义的格式,而是始终使用 FULL 格式。调用:

findAllByNextRollDateTimeLessThanEqual(LocalDateTime.now(ZoneOffset.UTC).truncatedTo(ChronoUnit.MINUTES));

给我以下异常(存储库中方法参数上的任何 @DateTimeFormat 或 @JsonFormat 注释都将被忽略):

Unrecognized chars at the end of [2019-07-22T09:07:00.000]: [:00.000]

如果我改为将存储库方法更改为接受一个字符串,并将一个格式与预期完全一致的字符串作为输入传递给它,它就没有问题。

是否有可能以某种方式定义用于在输入中传递给存储库方法的日期参数的格式,或者让 Spring 使用在字段本身上配置的格式?

我不想为这样的简单转换包装该方法(我做了并且它有效),并且我还想避免在日期字段中使用长类型

感谢和欢呼

作为参考,我也在Spring JIRA上打开问题

【问题讨论】:

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


    【解决方案1】:

    这些问题是我们放弃在 Spring Data Elasticsearch 中使用和公开 JacksonMapper 的原因之一。从 4.0 版开始,您的财产所需的只是一个注释:

    @Field(type = FieldType.Date, format = DateFormat.date_hour_minute)
    private LocalDateTime nextRollDateTime;
    

    这将用于编写索引映射、索引和检索实体时以及处理存储库方法和查询时。

    但是对于 3.2.x 版本,您将不得不使用您提到的包装之类的解决方法。

    【讨论】:

    • 这就是我们喜欢 Spring 项目的原因 :) 幸运的是,如果我没记错的话,v4 应该支持 ES 7,这就是我们要移动的地方。感谢更新
    猜你喜欢
    • 2016-05-10
    • 2021-03-03
    • 1970-01-01
    • 2022-01-06
    • 2015-11-09
    • 1970-01-01
    • 2019-11-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多