Elasticsearchのあるインデックスにdateタイプのフィールドを定義し、そこにバッチの開始日時を格納していた
dateタイプで使っているフォーマットはstrict_date_time
"startDateTime": { "type": "date", "format": "strict_date_time" },
strict_date_time
は日時のフォーマットが完璧なyyyy-MM-dd'T'HH:mm:ss.SSSZZ
の形でなくてはならない
Javaアプリケーション側では、そこにZonedDateTime型のプロパティを登録している
これで特に問題はないと思われたがたまにElasticsearch側でエラーが発生していた
エラーログは以下
ElasticsearchException[Elasticsearch exception [type=mapper_parsing_exception, reason=failed to parse field [startDateTime] of type [date]]]; nested: ElasticsearchException[Elasticsearch exception [type=illegal_argument_exception, reason=Invalid format: "2020-09-30T07:38:32Z" is malformed at "Z"]];
一見なにが問題かわからなかったが、どうやらyyyy-MM-dd'T'HH:mm:ss.SSSZZ
の.SSS
の部分が欠けていて、フォーマットにあっていないようだった
おそらくSSS
の部分が000
で、トリムされた模様
対策
JacksonのObjectMapperを使ってESに登録する前にjsonにシリアライズしているので、そこでZonedDateTime型に対してシリアライザを設定することにする
ObjectMapper mapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); module.addSerializer( ZonedDateTime.class, new ZonedDateTimeSerializer( DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX") .withZone(ZoneId.of("UTC")))); mapper.registerModule(module); String json = mapper.writeValueAsString(hoge);
これで、.SSS
の部分が欠けることなく登録することができるようになった