Spring Data Elasticsearch Repository查询强制日期参数格式

时间:2019-06-27 13:58:56

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

我使用的是Elasticsearch 6.5.3和Spring Boot 2.1.6以及spring-data-elasticsearch 3.2.0.M1(因为我想使用新的REST客户端进行连接,显然3.1.9尚不支持该功能)。

我有一个具有此字段的POJO AccountDateRollSchedule

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

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

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

查询索引还会返回按预期格式设置的字段:

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

我创建了一个扩展 ElasticsearchRepository 的存储库,并在其中声明了以下方法:

List<AccountDateRollSchedule> findAllByNextRollDateTimeLessThanEqual(@DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") Date dateTime);

日期为 java.util.Date 的地方,它将转换为以下查询:

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

但是将日期作为输入传递给方法,例如:

new Date()

给我以下异常(即使我在存储库方法参数上省略了 DateTimeFormat 批注):

Unrecognized chars at the end of [2019-06-30T13:34:46.386Z]: [.386Z]

...

ElasticsearchStatusException[Elasticsearch exception [type=search_phase_execution_exception, reason=all shards failed]
]

...

{"error":{"root_cause":[{"type":"parse_exception","reason":"failed to parse date field [2019-06-30T13:34:46.386Z] with format [date_hour_minute_second]"}],"type":"search_phase_execution_exception","reason":"all shards failed","phase":"query","grouped":true,"failed_shards":[{"shard":0,"index":"MYINDEX","node":"NODE","reason":{"type":"parse_exception","reason":"failed to parse date field [2019-06-30T13:34:46.386Z] with format [date_hour_minute_second]","caused_by":{"type":"illegal_argument_exception","reason":"Unrecognized chars at the end of [2019-06-30T13:34:46.386Z]: [.386Z]"}}}]},"status":400}

如果我改为将存储库方法更改为接受String并传递完全按预期格式设置的String作为输入,则它没有问题。

我在这里想念什么?

我不希望将这种方法包装为这样的简单转换(我确实做到了,并且可以正常工作),而且我还想避免在日期字段中使用长类型

感谢和欢呼

1 个答案:

答案 0 :(得分:1)

这些问题是我们不使用和公开Spring Data Elasticsearch中的JacksonMapper的原因之一。从版本4.0开始,您需要在媒体资源上添加一个注释:

"sendAudioChannel": {
            "googCodecName": "opus",
            "googRtt": null,
            "bytesSent": 22636,
            "packetsSent": 190,
            "packetsLost": null,
            "audioInputLevel": 0,
            "googJitterReceived": null,
            "googResidualEchoLikelihood": 0,
            "googEchoCancellationReturnLoss": -100,
            "googVoiceCaptureToPacketDelayMs": 0,
            "googEchoCancellationReturnLossEnhancement": -100
          }

然后将在编写索引映射,索引实体和检索实体以及处理存储库方法和查询时使用它。

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