Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change default format for date_nanos field #70463

Merged
merged 5 commits into from
Mar 17, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 2 additions & 10 deletions docs/reference/mapping/types/date_nanos.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,7 @@ back to a string depending on the date format that is associated with the field.
Date formats can be customised, but if no `format` is specified then it uses
the default:

"strict_date_optional_time||epoch_millis"

This means that it will accept dates with optional timestamps, which conform
to the formats supported by
<<strict-date-time,`strict_date_optional_time`>> including up to nine second
fractionals or milliseconds-since-the-epoch (thus losing precision on the
nano second part). Using <<strict-date-time,`strict_date_optional_time`>> will
format the result up to only three second fractionals. To
print and parse up to nine digits of resolution, use <<strict-date-time-nanos,`strict_date_optional_time_nanos`>>.
"strict_date_optional_time_nanos||epoch_millis"

For instance:

Expand Down Expand Up @@ -74,7 +66,7 @@ GET my-index-000001/_search
"docvalue_fields" : [
{
"field" : "date",
"format": "strict_date_time" <7>
"format": "strict_date_optional_time_nanos" <7>
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,3 +256,24 @@
- do:
indices.get_index_template:
name: my-it

---
"Verify date_nanos default format":
- do:
indices.create:
index: index_nanos
body:
mappings:
properties:
date:
type: date
date_nanos:
type: date_nanos

- do:
index:
index: index_nanos
id: 0
body:
date: "2015-01-01T12:10:30.123456789Z"
date_nanos: "2015-01-01T12:10:30.123456789Z"
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,16 @@
- match: {component_templates.0.component_template.template.settings: {index: {number_of_shards: '1', number_of_replicas: '0'}}}
- is_true: component_templates.0.component_template.template.mappings
- match: {component_templates.0.component_template.template.aliases: {aliasname: {}}}

---
"Verify date_nanos default format":
- do:
search:
index: index_nanos
body:
fields: ["date_nanos", "date"]

- match: { hits.total.value: 1 }
- match: { hits.hits.0._id: "0" }
- match: { hits.hits.0.fields.date: [ "2018-10-29T12:12:12.123Z" ] }
- match: { hits.hits.0.fields.date_nanos: [ "2018-10-29T12:12:12.123456789Z" ] }
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ public final class DateFieldMapper extends FieldMapper {
public static final String CONTENT_TYPE = "date";
public static final String DATE_NANOS_CONTENT_TYPE = "date_nanos";
public static final DateFormatter DEFAULT_DATE_TIME_FORMATTER = DateFormatter.forPattern("strict_date_optional_time||epoch_millis");
public static final DateFormatter DEFAULT_DATE_TIME_NANOS_FORMATTER = DateFormatter.forPattern("strict_date_optional_time_nanos||epoch_millis");
private static final DateMathParser EPOCH_MILLIS_PARSER = DateFormatter.forPattern("epoch_millis").toDateMathParser();

public enum Resolution {
Expand Down Expand Up @@ -216,8 +217,7 @@ public static class Builder extends FieldMapper.Builder {

private final Parameter<Map<String, String>> meta = Parameter.metaParam();

private final Parameter<String> format
= Parameter.stringParam("format", false, m -> toType(m).format, DEFAULT_DATE_TIME_FORMATTER.pattern());
private final Parameter<String> format;
private final Parameter<Locale> locale = new Parameter<>("locale", false, () -> Locale.ROOT,
(n, c, o) -> LocaleUtils.parse(o.toString()), m -> toType(m).locale);

Expand All @@ -235,6 +235,10 @@ public Builder(String name, Resolution resolution, DateFormatter dateFormatter,
this.indexCreatedVersion = indexCreatedVersion;
this.ignoreMalformed
= Parameter.boolParam("ignore_malformed", true, m -> toType(m).ignoreMalformed, ignoreMalformedByDefault);

DateFormatter defaultFormat = resolution == Resolution.MILLISECONDS ?
DEFAULT_DATE_TIME_FORMATTER : DEFAULT_DATE_TIME_NANOS_FORMATTER;
this.format = Parameter.stringParam("format", false, m -> toType(m).format, defaultFormat.pattern());
if (dateFormatter != null) {
this.format.setValue(dateFormatter.pattern());
this.locale.setValue(dateFormatter.locale());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,17 @@ public void testFetchDocValuesMillis() throws IOException {
assertEquals(List.of(date), fetchFromDocValues(mapperService, ft, format, 1589578382123L));
}

public void testFormatPreserveNanos() throws IOException {
MapperService mapperService = createMapperService(
fieldMapping(b -> b.field("type", "date_nanos"))
);
DateFieldMapper.DateFieldType ft = (DateFieldMapper.DateFieldType) mapperService.fieldType("field");
assertEquals(ft.dateTimeFormatter, DateFieldMapper.DEFAULT_DATE_TIME_NANOS_FORMATTER);
DocValueFormat format = ft.docValueFormat(null, null);
String date = "2020-05-15T21:33:02.123456789Z";
assertEquals(List.of(date), fetchFromDocValues(mapperService, ft, format, date));
}

public void testFetchDocValuesNanos() throws IOException {
MapperService mapperService = createMapperService(
fieldMapping(b -> b.field("type", "date_nanos").field("format", "strict_date_time||epoch_millis"))
Expand Down Expand Up @@ -494,7 +505,7 @@ private MapperService dateNanosMapperService() throws IOException {
}

private String randomIs8601Nanos(long maxMillis) {
String date = DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER.formatMillis(randomLongBetween(0, maxMillis));
String date = DateFieldMapper.DEFAULT_DATE_TIME_NANOS_FORMATTER.formatMillis(randomLongBetween(0, maxMillis));
date = date.substring(0, date.length() - 1); // Strip off trailing "Z"
return date + String.format(Locale.ROOT, "%06d", between(0, 999999)) + "Z"; // Add nanos and the "Z"
}
Expand Down