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:
Britta Weber 2013-10-15 17:28:35 +02:00
parent 2e8bbe9e30
commit c9dab6991e
6 changed files with 41 additions and 28 deletions

View File

@ -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

View File

@ -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.

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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)));
}
}

View File

@ -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();