0

我试图在我的 Elasticsearch 索引映射中指定我的日期格式,如本文档所述:https ://www.elastic.co/guide/en/elasticsearch/reference/current/date.html

我有一个这种格式的日期:2020-10-29T05:36:06.143Z[UTC]. 我如何将其转换为类似的格式YYYY-MM-DD...?具体来说,如何表示最后的[UTC]部分?

目前我有以下映射,我收到下面的错误,所以我试图指定日期的格式以查看它是否有效。谢谢!

    "createdTimeStamp": {
      "type": "date"
    },
Elasticsearch exception [type=mapper_parsing_exception, reason=failed to parse field [createdTimeStamp] of type [date] in document with id 'testId1'.

Preview of field's value: '{offset={totalSeconds=0, rules={fixedOffset=true, transitionRules=[], transitions=[]}, id=Z}, year=2015, dayOfYear=1, nano=0, chronology={calendarType=iso8601, id=ISO}, minute=10, second=30, dayOfWeek=THURSDAY, month=JANUARY, hour=12, zone={totalSeconds=0, rules={fixedOffset=true, transitionRules=[], transitions=[]}, id=Z}, dayOfMonth=1, monthValue=1}']];

nested: ElasticsearchException[Elasticsearch exception [type=illegal_state_exception, reason=Can't get text on a START_OBJECT at 1:72]]
4

2 回答 2

1

我没有 Elasticsearch 方面的专业知识。但是,以下解决方案应该可以帮助您解决问题。

您可以提及格式,如文档页面uuuu-MM-dd'T'HH:mm:ss.SSSX['['z']']上的示例所示。

演示:

import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        String strDateTime = "2020-10-29T05:36:06.143Z[UTC]";
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSX['['z']']");

        ZonedDateTime zdt = ZonedDateTime.parse(strDateTime, formatter);
        System.out.println(zdt);

        OffsetDateTime odt = OffsetDateTime.parse(strDateTime, formatter);
        System.out.println(odt);
    }
}

输出:

2020-10-29T05:36:06.143Z[UTC]
2020-10-29T05:36:06.143Z

['['z']']格式末尾的 使where和are literals成为'['z']' 可选的,同时指定时区。[]z

一些有用的信息:

您的日期时间字符串Z[UTC]末尾Z有一个重要的字母,指定Zulu日期时间,它只是UTC日期时间。换句话说,您的日期时间代表UTC. ZonedDateTime无需任何格式化程序即可解析它。

演示:

import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        String strDateTime = "2020-10-29T05:36:06.143Z[UTC]";
        ZonedDateTime zdt = ZonedDateTime.parse(strDateTime);
        System.out.println(zdt);
    }
}

输出:

2020-10-29T05:36:06.143Z[UTC]

但是,看起来 Elasticsearch 不ZonedDateTime用于解析日期时间字符串。文档页面提到默认格式是strict_date_optional_time或者epoch_millis如下引用:

可以自定义日期格式,但如果未指定格式,则使用默认格式:

“strict_date_optional_time||epoch_millis”

因此,为了符合默认格式,另一种方法是[UTC]从日期时间字符串的末尾删除。在此更改之后,字符串可以被所有 , 和 解析ZonedDateTimeOffsetDateTime并且Instant不需要任何格式化程序。

演示:

import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        String strDateTime = "2020-10-29T05:36:06.143Z[UTC]";
        strDateTime = strDateTime.substring(0, strDateTime.indexOf('['));
        System.out.println("Trimmed date-time string: " + strDateTime);

        ZonedDateTime zdt = ZonedDateTime.parse(strDateTime);
        System.out.println(zdt);

        OffsetDateTime odt = OffsetDateTime.parse(strDateTime);
        System.out.println(odt);

        Instant instant = Instant.parse(strDateTime);
        System.out.println(instant);
    }
}

输出:

Trimmed date-time string: 2020-10-29T05:36:06.143Z
2020-10-29T05:36:06.143Z
2020-10-29T05:36:06.143Z
2020-10-29T05:36:06.143Z
于 2020-11-26T19:02:22.477 回答
0

您首先需要对Z自身进行转义——它是一个代表区域偏移的符号,它本身不是一个有效值。

PUT myindex/
{
  "mappings": {
    "properties": {
      "createdTimeStamp": {
        "type": "date",
        "format": "yyyy-MM-dd'T'HH:mm:ss.SSS'Z[UTC]'"
      }
    }
  }
}

如果您确定所有传入的值都将采用 UTC,则可以将上述内容保持原样。这也将逃脱那[UTC]部分。

如果您希望有多个时区,则可以yyyy-MM-dd'T'HH:mm:ss.SSS'Z['z']'改用——小写字母z将为您解析传入的时区,并在内部以 UTC 格式存储日期,但有一个偏移量。这样,Z由于上述原因,您只会转义大写字母。

于 2020-11-24T09:41:34.673 回答