瀏覽代碼

updated rangetype to be more inline with the docs (https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-query.html) and added tests to reflect as much (#113872)

john-wagster 1 年之前
父節點
當前提交
8a8ad1b815

+ 1 - 1
docs/reference/mapping/types/range.asciidoc

@@ -465,7 +465,7 @@ Will become:
     },
     {
       "gte": "2017-09-01T00:00:00.000Z",
-      "lte": "2017-09-10T00:00:00.000Z"
+      "lte": "2017-09-10T23:59:59.999Z"
     }
   ]
 }

+ 71 - 0
rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/range/10_basic.yml

@@ -446,6 +446,77 @@ setup:
 
   - match: { hits.total: 2 }
 
+---
+"Date range edge cases":
+  - requires:
+      cluster_features: ["mapper.range.date_range_indexing_fix"]
+      reason: "tests rounding fixes in 8.16.0 that previously caused non-intuitive indexing and query because ranges were assumed to always index with 0's as the default such as when time is missing 00:00:00.000 time was assumed but for lte indexing and query missing time should be 23:59:59.999 as per docs here: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-query.html"
+
+  - do:
+      indices.create:
+        index: test_date_range_edge_cases
+        body:
+          mappings:
+            "properties":
+              "date_range":
+                "type": "date_range"
+                "format": "yyyy-MM-dd"
+
+  - do:
+      index:
+        index: test_date_range_edge_cases
+        id: "1"
+        body: { "date_range": { "gte": "1980-12-14", "lte": "1980-12-17" } }
+
+  - do:
+      index:
+        index: test_date_range_edge_cases
+        id: "2"
+        body: { "date_range": { "gt": "1990-12-15", "lt": "1990-12-18" } }
+
+  - do:
+      index:
+        index: test_date_range_edge_cases
+        id: "3"
+        body: { "date_range": { "gte": "1985-12-16||/M", "lte": "1986-02-10||/M" } }
+
+  - do:
+      index:
+        index: test_date_range_edge_cases
+        id: "4"
+        body: { "date_range": { "gt": "1995-12-16||/M", "lt": "1996-02-10||/M" } }
+
+  - do:
+      indices.refresh: { }
+
+  - do:
+      search:
+        rest_total_hits_as_int: true
+        body: { "size": 0, "query": { "range": { "date_range": { "gte": "1980-12-14", "lte": "1980-12-17", "relation": "contains" } } } }
+
+  - match: { hits.total: 1 }
+
+  - do:
+      search:
+        rest_total_hits_as_int: true
+        body: { "size": 0, "query": { "range": { "date_range": { "gt": "1990-12-15", "lt": "1990-12-18", "relation": "contains" } } } }
+
+  - match: { hits.total: 1 }
+
+  - do:
+      search:
+        rest_total_hits_as_int: true
+        body: { "size": 0, "query": { "range": { "date_range": { "gte": "1985-12-16||/M", "lte": "1986-02-10||/M", "relation": "contains" } } } }
+
+  - match: { hits.total: 1 }
+
+  - do:
+      search:
+        rest_total_hits_as_int: true
+        body: { "size": 0, "query": { "range": { "date_range": { "gt": "1995-12-16||/M", "lt": "1996-02-10||/M", "relation": "contains" } } } }
+
+  - match: { hits.total: 1 }
+
 ---
 "Null bounds":
 

+ 137 - 0
rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/range/20_synthetic_source.yml

@@ -527,6 +527,9 @@ setup:
 
 ---
 "Date range":
+  - skip:
+      cluster_features: ["mapper.range.date_range_indexing_fix"]
+      reason: "tests prior to rounding fixes in 8.16.0 that caused non-intuitive indexing and query because ranges were assumed to always index with 0's as the default such as when time is missing 00:00:00.000 time was assumed but for lte indexing and query missing time should be 23:59:59.999 as per docs here: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-query.html"
 
   - do:
       index:
@@ -655,3 +658,137 @@ setup:
   - match:
       _source:
         date_range: { "gte": "2017-09-05T00:00:00.000Z", "lte": null }
+
+---
+"Date range Rounding Fixes":
+  - requires:
+      cluster_features: ["mapper.range.date_range_indexing_fix"]
+      reason: "tests rounding fixes in 8.16.0 that previously caused non-intuitive indexing and query because ranges were assumed to always index with 0's as the default such as when time is missing 00:00:00.000 time was assumed but for lte indexing and query missing time should be 23:59:59.999 as per docs here: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-query.html"
+
+  - do:
+      index:
+        index: synthetic_source_test
+        id: "1"
+        body: { "date_range": { "gte": "2017-09-01", "lte": "2017-09-05" } }
+
+  - do:
+      index:
+        index: synthetic_source_test
+        id: "2"
+        body: { "date_range": { "gt": "2017-09-01", "lte": "2017-09-03" } }
+
+  - do:
+      index:
+        index: synthetic_source_test
+        id: "3"
+        body: { "date_range": [ { "gte": "2017-09-04", "lt": "2017-09-05" } ] }
+
+  - do:
+      index:
+        index: synthetic_source_test
+        id: "4"
+        body: { "date_range": [ { "gt": "2017-09-04", "lt": "2017-09-08" }, { "gt": "2017-09-04", "lt": "2017-09-07" } ] }
+
+  - do:
+      index:
+        index: synthetic_source_test
+        id: "5"
+        body: { "date_range": { "gte": 1504224000000, "lte": 1504569600000 } }
+
+  - do:
+      index:
+        index: synthetic_source_test
+        id: "6"
+        body: { "date_range": { "gte": "2017-09-01T10:20:30.123Z", "lte": "2017-09-05T03:04:05.789Z" } }
+
+  - do:
+      index:
+        index: synthetic_source_test
+        id: "7"
+        body: { "date_range": null }
+
+  - do:
+      index:
+        index: synthetic_source_test
+        id: "8"
+        body: { "date_range": { "gte": null, "lte": "2017-09-05" } }
+
+  - do:
+      index:
+        index: synthetic_source_test
+        id: "9"
+        body: { "date_range": { "gte": "2017-09-05" } }
+
+  - do:
+      indices.refresh: { }
+
+  - do:
+      get:
+        index: synthetic_source_test
+        id: "1"
+  - match:
+      _source:
+        date_range: { "gte": "2017-09-01T00:00:00.000Z", "lte": "2017-09-05T23:59:59.999Z" }
+
+  - do:
+      get:
+        index: synthetic_source_test
+        id: "2"
+  - match:
+      _source:
+        date_range: { "gte": "2017-09-02T00:00:00.000Z", "lte": "2017-09-03T23:59:59.999Z" }
+
+  - do:
+      get:
+        index: synthetic_source_test
+        id: "3"
+  - match:
+      _source:
+        date_range: { "gte": "2017-09-04T00:00:00.000Z", "lte": "2017-09-04T23:59:59.999Z" }
+
+  - do:
+      get:
+        index: synthetic_source_test
+        id: "4"
+  - match:
+      _source:
+        date_range: [ { "gte": "2017-09-05T00:00:00.000Z", "lte": "2017-09-06T23:59:59.999Z" }, { "gte": "2017-09-05T00:00:00.000Z", "lte": "2017-09-07T23:59:59.999Z" } ]
+
+  - do:
+      get:
+        index: synthetic_source_test
+        id: "5"
+  - match:
+      _source:
+        date_range: { "gte": "2017-09-01T00:00:00.000Z", "lte": "2017-09-05T00:00:00.000Z" }
+
+  - do:
+      get:
+        index: synthetic_source_test
+        id: "6"
+  - match:
+      _source:
+        date_range: { "gte": "2017-09-01T10:20:30.123Z", "lte": "2017-09-05T03:04:05.789Z" }
+
+  - do:
+      get:
+        index: synthetic_source_test
+        id: "7"
+  - match:
+      _source: { }
+
+  - do:
+      get:
+        index: synthetic_source_test
+        id: "8"
+  - match:
+      _source:
+        date_range: { "gte": null, "lte": "2017-09-05T23:59:59.999Z" }
+
+  - do:
+      get:
+        index: synthetic_source_test
+        id: "9"
+  - match:
+      _source:
+        date_range: { "gte": "2017-09-05T00:00:00.000Z", "lte": null }

+ 5 - 0
server/src/main/java/org/elasticsearch/index/mapper/MapperFeatures.java

@@ -49,4 +49,9 @@ public class MapperFeatures implements FeatureSpecification {
             FlattenedFieldMapper.IGNORE_ABOVE_WITH_ARRAYS_SUPPORT
         );
     }
+
+    @Override
+    public Set<NodeFeature> getTestFeatures() {
+        return Set.of(RangeFieldMapper.DATE_RANGE_INDEXING_FIX);
+    }
 }

+ 1 - 0
server/src/main/java/org/elasticsearch/index/mapper/RangeFieldMapper.java

@@ -52,6 +52,7 @@ import static org.elasticsearch.index.query.RangeQueryBuilder.LT_FIELD;
 /** A {@link FieldMapper} for indexing numeric and date ranges, and creating queries */
 public class RangeFieldMapper extends FieldMapper {
     public static final NodeFeature NULL_VALUES_OFF_BY_ONE_FIX = new NodeFeature("mapper.range.null_values_off_by_one_fix");
+    public static final NodeFeature DATE_RANGE_INDEXING_FIX = new NodeFeature("mapper.range.date_range_indexing_fix");
 
     public static final boolean DEFAULT_INCLUDE_UPPER = true;
     public static final boolean DEFAULT_INCLUDE_LOWER = true;

+ 9 - 2
server/src/main/java/org/elasticsearch/index/mapper/RangeType.java

@@ -196,14 +196,20 @@ public enum RangeType {
         @Override
         public Number parseFrom(RangeFieldMapper.RangeFieldType fieldType, XContentParser parser, boolean coerce, boolean included)
             throws IOException {
-            Number value = parseValue(parser.text(), coerce, fieldType.dateMathParser);
+            assert fieldType.dateMathParser != null;
+            Number value = fieldType.dateMathParser.parse(parser.text(), () -> {
+                throw new IllegalArgumentException("now is not used at indexing time");
+            }, included == false, null).toEpochMilli();
             return included ? value : nextUp(value);
         }
 
         @Override
         public Number parseTo(RangeFieldMapper.RangeFieldType fieldType, XContentParser parser, boolean coerce, boolean included)
             throws IOException {
-            Number value = parseValue(parser.text(), coerce, fieldType.dateMathParser);
+            assert fieldType.dateMathParser != null;
+            Number value = fieldType.dateMathParser.parse(parser.text(), () -> {
+                throw new IllegalArgumentException("now is not used at indexing time");
+            }, included, null).toEpochMilli();
             return included ? value : nextDown(value);
         }
 
@@ -295,6 +301,7 @@ public enum RangeType {
                     roundUp,
                     zone
                 ).toEpochMilli();
+
             roundUp = includeUpper; // using "lte" should round upper bound up
             Long high = upperTerm == null
                 ? maxValue()

+ 1 - 1
server/src/test/java/org/elasticsearch/index/mapper/DateRangeFieldMapperTests.java

@@ -33,7 +33,7 @@ public class DateRangeFieldMapperTests extends RangeFieldMapperTests {
 
     @Override
     protected String storedValue() {
-        return "1477872000000";
+        return "1477958399999";
     }
 
     @Override