Browse Source

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
Britta Weber 12 years ago
parent
commit
c9dab6991e

+ 4 - 0
docs/reference/mapping/date-format.asciidoc

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

+ 8 - 8
src/main/java/org/elasticsearch/common/joda/DateMathParser.java

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

+ 19 - 11
src/main/java/org/elasticsearch/index/mapper/core/DateFieldMapper.java

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

+ 7 - 6
src/main/java/org/elasticsearch/index/mapper/internal/TimestampFieldMapper.java

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

+ 2 - 2
src/test/java/org/elasticsearch/common/joda/DateMathParserTests.java

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

+ 1 - 1
src/test/java/org/elasticsearch/search/simple/SimpleSearchTests.java

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