rename and document "index.mapping.date.parse_upper_inclusive" setting for date fields
The setting causes the upper bound for a range query/filter to be rounded up, therefore the name `round_ceil` seems to make more sense. Also this commit removes the redundant fourth parameter to DateMathParser.parse(..) which was never used. was: parse(String text, long now, boolean roundUp, boolean upperInclusive) is now: parse(String text, long now, boolean roundCeil) closes #3914
This commit is contained in:
parent
2e8bbe9e30
commit
c9dab6991e
|
@ -39,6 +39,10 @@ Note, when doing `range` type searches, and the upper value is
|
|||
inclusive, the rounding will properly be rounded to the ceiling instead
|
||||
of flooring it.
|
||||
|
||||
To change this behavior, set
|
||||
`"mapping.date.round_ceil": false`.
|
||||
|
||||
|
||||
[float]
|
||||
[[built-in]]
|
||||
=== Built In Formats
|
||||
|
|
|
@ -20,14 +20,14 @@ public class DateMathParser {
|
|||
}
|
||||
|
||||
public long parse(String text, long now) {
|
||||
return parse(text, now, false, false);
|
||||
return parse(text, now, false);
|
||||
}
|
||||
|
||||
public long parseUpperInclusive(String text, long now) {
|
||||
return parse(text, now, true, true);
|
||||
public long parseRoundCeil(String text, long now) {
|
||||
return parse(text, now, true);
|
||||
}
|
||||
|
||||
public long parse(String text, long now, boolean roundUp, boolean upperInclusive) {
|
||||
public long parse(String text, long now, boolean roundCeil) {
|
||||
long time;
|
||||
String mathString;
|
||||
if (text.startsWith("now")) {
|
||||
|
@ -43,8 +43,8 @@ public class DateMathParser {
|
|||
parseString = text.substring(0, index);
|
||||
mathString = text.substring(index + 2);
|
||||
}
|
||||
if (upperInclusive) {
|
||||
time = parseUpperInclusiveStringValue(parseString);
|
||||
if (roundCeil) {
|
||||
time = parseRoundCeilStringValue(parseString);
|
||||
} else {
|
||||
time = parseStringValue(parseString);
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ public class DateMathParser {
|
|||
return time;
|
||||
}
|
||||
|
||||
return parseMath(mathString, time, roundUp);
|
||||
return parseMath(mathString, time, roundCeil);
|
||||
}
|
||||
|
||||
private long parseMath(String mathString, long time, boolean roundUp) throws ElasticSearchParseException {
|
||||
|
@ -209,7 +209,7 @@ public class DateMathParser {
|
|||
}
|
||||
}
|
||||
|
||||
private long parseUpperInclusiveStringValue(String value) {
|
||||
private long parseRoundCeilStringValue(String value) {
|
||||
try {
|
||||
// we create a date time for inclusive upper range, we "include" by default the day level data
|
||||
// so something like 2011-01-01 will include the full first day of 2011.
|
||||
|
|
|
@ -81,7 +81,7 @@ public class DateFieldMapper extends NumberFieldMapper<Long> {
|
|||
public static final String NULL_VALUE = null;
|
||||
|
||||
public static final TimeUnit TIME_UNIT = TimeUnit.MILLISECONDS;
|
||||
public static final boolean PARSE_UPPER_INCLUSIVE = true;
|
||||
public static final boolean ROUND_CEIL = true;
|
||||
}
|
||||
|
||||
public static class Builder extends NumberFieldMapper.Builder<Builder, DateFieldMapper> {
|
||||
|
@ -118,16 +118,17 @@ public class DateFieldMapper extends NumberFieldMapper<Long> {
|
|||
|
||||
@Override
|
||||
public DateFieldMapper build(BuilderContext context) {
|
||||
boolean parseUpperInclusive = Defaults.PARSE_UPPER_INCLUSIVE;
|
||||
boolean roundCeil = Defaults.ROUND_CEIL;
|
||||
if (context.indexSettings() != null) {
|
||||
parseUpperInclusive = context.indexSettings().getAsBoolean("index.mapping.date.parse_upper_inclusive", Defaults.PARSE_UPPER_INCLUSIVE);
|
||||
Settings settings = context.indexSettings();
|
||||
roundCeil = settings.getAsBoolean("index.mapping.date.round_ceil", settings.getAsBoolean("index.mapping.date.parse_upper_inclusive", Defaults.ROUND_CEIL));
|
||||
}
|
||||
fieldType.setOmitNorms(fieldType.omitNorms() && boost == 1.0f);
|
||||
if (!locale.equals(dateTimeFormatter.locale())) {
|
||||
dateTimeFormatter = new FormatDateTimeFormatter(dateTimeFormatter.format(), dateTimeFormatter.parser(), dateTimeFormatter.printer(), locale);
|
||||
}
|
||||
DateFieldMapper fieldMapper = new DateFieldMapper(buildNames(context), dateTimeFormatter,
|
||||
precisionStep, boost, fieldType, nullValue, timeUnit, parseUpperInclusive, ignoreMalformed(context),
|
||||
precisionStep, boost, fieldType, nullValue, timeUnit, roundCeil, ignoreMalformed(context),
|
||||
postingsProvider, docValuesProvider, similarity, fieldDataSettings, context.indexSettings());
|
||||
fieldMapper.includeInAll(includeInAll);
|
||||
return fieldMapper;
|
||||
|
@ -184,7 +185,14 @@ public class DateFieldMapper extends NumberFieldMapper<Long> {
|
|||
|
||||
protected final FormatDateTimeFormatter dateTimeFormatter;
|
||||
|
||||
private final boolean parseUpperInclusive;
|
||||
// Triggers rounding up of the upper bound for range queries and filters if
|
||||
// set to true.
|
||||
// Rounding up a date here has the following meaning: If a date is not
|
||||
// defined with full precision, for example, no milliseconds given, the date
|
||||
// will be filled up to the next larger date with that precision.
|
||||
// Example: An upper bound given as "2000-01-01", will be converted to
|
||||
// "2000-01-01T23.59.59.999"
|
||||
private final boolean roundCeil;
|
||||
|
||||
private final DateMathParser dateMathParser;
|
||||
|
||||
|
@ -193,7 +201,7 @@ public class DateFieldMapper extends NumberFieldMapper<Long> {
|
|||
protected final TimeUnit timeUnit;
|
||||
|
||||
protected DateFieldMapper(Names names, FormatDateTimeFormatter dateTimeFormatter, int precisionStep, float boost, FieldType fieldType,
|
||||
String nullValue, TimeUnit timeUnit, boolean parseUpperInclusive, Explicit<Boolean> ignoreMalformed,
|
||||
String nullValue, TimeUnit timeUnit, boolean roundCeil, Explicit<Boolean> ignoreMalformed,
|
||||
PostingsFormatProvider postingsProvider, DocValuesFormatProvider docValuesProvider, SimilarityProvider similarity,
|
||||
@Nullable Settings fieldDataSettings, Settings indexSettings) {
|
||||
super(names, precisionStep, boost, fieldType, ignoreMalformed, new NamedAnalyzer("_date/" + precisionStep,
|
||||
|
@ -203,7 +211,7 @@ public class DateFieldMapper extends NumberFieldMapper<Long> {
|
|||
this.dateTimeFormatter = dateTimeFormatter;
|
||||
this.nullValue = nullValue;
|
||||
this.timeUnit = timeUnit;
|
||||
this.parseUpperInclusive = parseUpperInclusive;
|
||||
this.roundCeil = roundCeil;
|
||||
this.dateMathParser = new DateMathParser(dateTimeFormatter, timeUnit);
|
||||
}
|
||||
|
||||
|
@ -305,7 +313,7 @@ public class DateFieldMapper extends NumberFieldMapper<Long> {
|
|||
|
||||
public long parseToMilliseconds(Object value, @Nullable QueryParseContext context, boolean includeUpper) {
|
||||
long now = context == null ? System.currentTimeMillis() : context.nowInMillis();
|
||||
return includeUpper ? dateMathParser.parseUpperInclusive(convertToString(value), now) : dateMathParser.parse(convertToString(value), now);
|
||||
return includeUpper && roundCeil ? dateMathParser.parseRoundCeil(convertToString(value), now) : dateMathParser.parse(convertToString(value), now);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -319,7 +327,7 @@ public class DateFieldMapper extends NumberFieldMapper<Long> {
|
|||
public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
|
||||
return NumericRangeQuery.newLongRange(names.indexName(), precisionStep,
|
||||
lowerTerm == null ? null : parseToMilliseconds(lowerTerm, context),
|
||||
upperTerm == null ? null : parseToMilliseconds(upperTerm, context, includeUpper && parseUpperInclusive),
|
||||
upperTerm == null ? null : parseToMilliseconds(upperTerm, context, includeUpper),
|
||||
includeLower, includeUpper);
|
||||
}
|
||||
|
||||
|
@ -327,7 +335,7 @@ public class DateFieldMapper extends NumberFieldMapper<Long> {
|
|||
public Filter rangeFilter(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
|
||||
return NumericRangeFilter.newLongRange(names.indexName(), precisionStep,
|
||||
lowerTerm == null ? null : parseToMilliseconds(lowerTerm, context),
|
||||
upperTerm == null ? null : parseToMilliseconds(upperTerm, context, includeUpper && parseUpperInclusive),
|
||||
upperTerm == null ? null : parseToMilliseconds(upperTerm, context, includeUpper),
|
||||
includeLower, includeUpper);
|
||||
}
|
||||
|
||||
|
@ -335,7 +343,7 @@ public class DateFieldMapper extends NumberFieldMapper<Long> {
|
|||
public Filter rangeFilter(IndexFieldDataService fieldData, Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
|
||||
return NumericRangeFieldDataFilter.newLongRange((IndexNumericFieldData<?>) fieldData.getForField(this),
|
||||
lowerTerm == null ? null : parseToMilliseconds(lowerTerm, context),
|
||||
upperTerm == null ? null : parseToMilliseconds(upperTerm, context, includeUpper && parseUpperInclusive),
|
||||
upperTerm == null ? null : parseToMilliseconds(upperTerm, context, includeUpper),
|
||||
includeLower, includeUpper);
|
||||
}
|
||||
|
||||
|
|
|
@ -99,11 +99,12 @@ public class TimestampFieldMapper extends DateFieldMapper implements InternalMap
|
|||
|
||||
@Override
|
||||
public TimestampFieldMapper build(BuilderContext context) {
|
||||
boolean parseUpperInclusive = Defaults.PARSE_UPPER_INCLUSIVE;
|
||||
boolean roundCeil = Defaults.ROUND_CEIL;
|
||||
if (context.indexSettings() != null) {
|
||||
parseUpperInclusive = context.indexSettings().getAsBoolean("index.mapping.date.parse_upper_inclusive", Defaults.PARSE_UPPER_INCLUSIVE);
|
||||
Settings settings = context.indexSettings();
|
||||
roundCeil = settings.getAsBoolean("index.mapping.date.round_ceil", settings.getAsBoolean("index.mapping.date.parse_upper_inclusive", Defaults.ROUND_CEIL));
|
||||
}
|
||||
return new TimestampFieldMapper(fieldType, enabledState, path, dateTimeFormatter, parseUpperInclusive,
|
||||
return new TimestampFieldMapper(fieldType, enabledState, path, dateTimeFormatter, roundCeil,
|
||||
ignoreMalformed(context), postingsProvider, docValuesProvider, fieldDataSettings, context.indexSettings());
|
||||
}
|
||||
}
|
||||
|
@ -136,18 +137,18 @@ public class TimestampFieldMapper extends DateFieldMapper implements InternalMap
|
|||
|
||||
public TimestampFieldMapper() {
|
||||
this(new FieldType(Defaults.FIELD_TYPE), Defaults.ENABLED, Defaults.PATH, Defaults.DATE_TIME_FORMATTER,
|
||||
Defaults.PARSE_UPPER_INCLUSIVE, Defaults.IGNORE_MALFORMED, null, null, null, ImmutableSettings.EMPTY);
|
||||
Defaults.ROUND_CEIL, Defaults.IGNORE_MALFORMED, null, null, null, ImmutableSettings.EMPTY);
|
||||
}
|
||||
|
||||
protected TimestampFieldMapper(FieldType fieldType, EnabledAttributeMapper enabledState, String path,
|
||||
FormatDateTimeFormatter dateTimeFormatter, boolean parseUpperInclusive,
|
||||
FormatDateTimeFormatter dateTimeFormatter, boolean roundCeil,
|
||||
Explicit<Boolean> ignoreMalformed, PostingsFormatProvider postingsProvider,
|
||||
DocValuesFormatProvider docValuesProvider, @Nullable Settings fieldDataSettings,
|
||||
Settings indexSettings) {
|
||||
super(new Names(Defaults.NAME, Defaults.NAME, Defaults.NAME, Defaults.NAME), dateTimeFormatter,
|
||||
Defaults.PRECISION_STEP, Defaults.BOOST, fieldType,
|
||||
Defaults.NULL_VALUE, TimeUnit.MILLISECONDS /*always milliseconds*/,
|
||||
parseUpperInclusive, ignoreMalformed, postingsProvider, docValuesProvider, null, fieldDataSettings, indexSettings);
|
||||
roundCeil, ignoreMalformed, postingsProvider, docValuesProvider, null, fieldDataSettings, indexSettings);
|
||||
this.enabledState = enabledState;
|
||||
this.path = path;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ public class DateMathParserTests extends ElasticsearchTestCase {
|
|||
assertThat(parser.parse("now+1m-1s", 0), equalTo(TimeUnit.MINUTES.toMillis(1) - TimeUnit.SECONDS.toMillis(1)));
|
||||
|
||||
assertThat(parser.parse("now+1m+1s/m", 0), equalTo(TimeUnit.MINUTES.toMillis(1)));
|
||||
assertThat(parser.parseUpperInclusive("now+1m+1s/m", 0), equalTo(TimeUnit.MINUTES.toMillis(2)));
|
||||
assertThat(parser.parseRoundCeil("now+1m+1s/m", 0), equalTo(TimeUnit.MINUTES.toMillis(2)));
|
||||
|
||||
assertThat(parser.parse("now+4y", 0), equalTo(TimeUnit.DAYS.toMillis(4*365 + 1)));
|
||||
}
|
||||
|
@ -42,6 +42,6 @@ public class DateMathParserTests extends ElasticsearchTestCase {
|
|||
|
||||
assertThat(parser.parse("2013-01-01||+1y", 0), equalTo(parser.parse("2013-01-01", 0) + TimeUnit.DAYS.toMillis(365)));
|
||||
assertThat(parser.parse("2013-03-03||/y", 0), equalTo(parser.parse("2013-01-01", 0)));
|
||||
assertThat(parser.parseUpperInclusive("2013-03-03||/y", 0), equalTo(parser.parse("2014-01-01", 0)));
|
||||
assertThat(parser.parseRoundCeil("2013-03-03||/y", 0), equalTo(parser.parse("2014-01-01", 0)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -130,7 +130,7 @@ public class SimpleSearchTests extends AbstractIntegrationTest {
|
|||
|
||||
@Test
|
||||
public void simpleDateRangeWithUpperInclusiveDisabledTests() throws Exception {
|
||||
prepareCreate("test").setSettings(ImmutableSettings.settingsBuilder().put("index.mapping.date.parse_upper_inclusive", false)).execute().actionGet();
|
||||
prepareCreate("test").setSettings(ImmutableSettings.settingsBuilder().put("index.mapping.date.round_ceil", false)).execute().actionGet();
|
||||
client().prepareIndex("test", "type1", "1").setSource("field", "2010-01-05T02:00").execute().actionGet();
|
||||
client().prepareIndex("test", "type1", "2").setSource("field", "2010-01-06T02:00").execute().actionGet();
|
||||
ensureGreen();
|
||||
|
|
Loading…
Reference in New Issue