Просмотр исходного кода

`ip_range` aggregation should accept null bounds. (#21043)

* `ip_range` aggregation should accept null bounds.

Closes #21006

* test

* iter
Adrien Grand 9 лет назад
Родитель
Сommit
d88239ba63

+ 2 - 2
core/src/main/java/org/elasticsearch/search/aggregations/bucket/range/ip/IpRangeParser.java

@@ -82,9 +82,9 @@ public class IpRangeParser extends BytesValuesSourceParser {
             if (parseFieldMatcher.match(parser.currentName(), RangeAggregator.Range.KEY_FIELD)) {
                 key = parser.text();
             } else if (parseFieldMatcher.match(parser.currentName(), RangeAggregator.Range.FROM_FIELD)) {
-                from = parser.text();
+                from = parser.textOrNull();
             } else if (parseFieldMatcher.match(parser.currentName(), RangeAggregator.Range.TO_FIELD)) {
-                to = parser.text();
+                to = parser.textOrNull();
             } else if (parseFieldMatcher.match(parser.currentName(), MASK_FIELD)) {
                 mask = parser.text();
             } else {

+ 226 - 0
rest-api-spec/src/main/resources/rest-api-spec/test/search.aggregation/40_range.yaml

@@ -0,0 +1,226 @@
+setup:
+  - do:
+      indices.create:
+          index: test
+          body:
+            settings:
+              number_of_replicas: 0
+            mappings:
+              test:
+                properties:
+                  ip:
+                     type: ip
+                  double:
+                    type: double
+                  date:
+                    type: date
+
+  - do:
+      cluster.health:
+        wait_for_status: green
+
+---
+"Double range":
+  - do:
+      index:
+        index: test
+        type: test
+        id: 1
+        body: { "double" : 42 }
+
+  - do:
+      index:
+        index: test
+        type: test
+        id: 2
+        body: { "double" : 100 }
+
+  - do:
+      index:
+        index: test
+        type: test
+        id: 3
+        body: { "double" : 50 }
+
+  - do:
+      indices.refresh: {}
+
+  - do:
+      search:
+        body: { "size" : 0, "aggs" : { "double_range" : { "range" : { "field" : "double", "ranges": [ { "to": 50 }, { "from": 50, "to": 150 }, { "from": 150 } ] } } } }
+
+  - match: { hits.total: 3 }
+
+  - length: { aggregations.double_range.buckets: 3 }
+
+  - match: { aggregations.double_range.buckets.0.key: "*-50.0" }
+
+  - is_false: aggregations.double_range.buckets.0.from
+
+  - match: { aggregations.double_range.buckets.0.to: 50.0 }
+
+  - match: { aggregations.double_range.buckets.0.doc_count: 1 }
+
+  - match: { aggregations.double_range.buckets.1.key: "50.0-150.0" }
+
+  - match: { aggregations.double_range.buckets.1.from: 50.0 }
+
+  - match: { aggregations.double_range.buckets.1.to: 150.0 }
+
+  - match: { aggregations.double_range.buckets.1.doc_count: 2 }
+
+  - match: { aggregations.double_range.buckets.2.key: "150.0-*" }
+
+  - match: { aggregations.double_range.buckets.2.from: 150.0 }
+
+  - is_false:  aggregations.double_range.buckets.2.to
+
+  - match: { aggregations.double_range.buckets.2.doc_count: 0 }
+
+  - do:
+      search:
+        body: { "size" : 0, "aggs" : { "double_range" : { "range" : { "field" : "double", "ranges": [ { "from": null, "to": 50 }, { "from": 50, "to": 150 }, { "from": 150, "to": null } ] } } } }
+
+  - match: { hits.total: 3 }
+
+  - length: { aggregations.double_range.buckets: 3 }
+
+  - match: { aggregations.double_range.buckets.0.key: "*-50.0" }
+
+  - is_false: aggregations.double_range.buckets.0.from
+
+  - match: { aggregations.double_range.buckets.0.to: 50.0 }
+
+  - match: { aggregations.double_range.buckets.0.doc_count: 1 }
+
+  - match: { aggregations.double_range.buckets.1.key: "50.0-150.0" }
+
+  - match: { aggregations.double_range.buckets.1.from: 50.0 }
+
+  - match: { aggregations.double_range.buckets.1.to: 150.0 }
+
+  - match: { aggregations.double_range.buckets.1.doc_count: 2 }
+
+  - match: { aggregations.double_range.buckets.2.key: "150.0-*" }
+
+  - match: { aggregations.double_range.buckets.2.from: 150.0 }
+
+  - is_false:  aggregations.double_range.buckets.2.to
+
+  - match: { aggregations.double_range.buckets.2.doc_count: 0 }
+
+---
+"IP range":
+  - do:
+      index:
+        index: test
+        type: test
+        id: 1
+        body: { "ip" : "::1" }
+
+  - do:
+      index:
+        index: test
+        type: test
+        id: 2
+        body: { "ip" : "192.168.0.1" }
+
+  - do:
+      index:
+        index: test
+        type: test
+        id: 3
+        body: { "ip" : "192.168.0.7" }
+
+  - do:
+      indices.refresh: {}
+
+  - do:
+      search:
+        body: { "size" : 0, "aggs" : { "ip_range" : { "ip_range" : { "field" : "ip", "ranges": [ { "to": "192.168.0.0" }, { "from": "192.168.0.0", "to": "192.169.0.0" }, { "from": "192.169.0.0" } ] } } } }
+
+  - match: { hits.total: 3 }
+
+  - length: { aggregations.ip_range.buckets: 3 }
+
+# ip_range does not automatically add keys to buckets, see #21045
+#  - match: { aggregations.ip_range.buckets.0.key: "*-192.168.0.0" }
+
+  - is_false: aggregations.ip_range.buckets.0.from
+
+  - match: { aggregations.ip_range.buckets.0.to: "192.168.0.0" }
+
+  - match: { aggregations.ip_range.buckets.0.doc_count: 1 }
+
+#  - match: { aggregations.ip_range.buckets.1.key: "192.168.0.0-192.169.0.0" }
+
+  - match: { aggregations.ip_range.buckets.1.from: "192.168.0.0" }
+
+  - match: { aggregations.ip_range.buckets.1.to: "192.169.0.0" }
+
+  - match: { aggregations.ip_range.buckets.1.doc_count: 2 }
+
+#  - match: { aggregations.ip_range.buckets.2.key: "192.169.0.0-*" }
+
+  - match: { aggregations.ip_range.buckets.2.from: "192.169.0.0" }
+
+  - is_false:  aggregations.ip_range.buckets.2.to
+
+  - match: { aggregations.ip_range.buckets.2.doc_count: 0 }
+
+  - do:
+      search:
+        body: { "size" : 0, "aggs" : { "ip_range" : { "ip_range" : { "field" : "ip", "ranges": [ { "from": null, "to": "192.168.0.0" }, { "from": "192.168.0.0", "to": "192.169.0.0" }, { "from": "192.169.0.0", "to": null } ] } } } }
+
+  - match: { hits.total: 3 }
+
+  - length: { aggregations.ip_range.buckets: 3 }
+
+#  - match: { aggregations.ip_range.buckets.0.key: "*-192.168.0.0" }
+
+  - is_false: aggregations.ip_range.buckets.0.from
+
+  - match: { aggregations.ip_range.buckets.0.to: "192.168.0.0" }
+
+  - match: { aggregations.ip_range.buckets.0.doc_count: 1 }
+
+#  - match: { aggregations.ip_range.buckets.1.key: "192.168.0.0-192.169.0.0" }
+
+  - match: { aggregations.ip_range.buckets.1.from: "192.168.0.0" }
+
+  - match: { aggregations.ip_range.buckets.1.to: "192.169.0.0" }
+
+  - match: { aggregations.ip_range.buckets.1.doc_count: 2 }
+
+#  - match: { aggregations.ip_range.buckets.2.key: "192.169.0.0-*" }
+
+  - match: { aggregations.ip_range.buckets.2.from: "192.169.0.0" }
+
+  - is_false:  aggregations.ip_range.buckets.2.to
+
+  - match: { aggregations.ip_range.buckets.2.doc_count: 0 }
+
+  - do:
+      search:
+        body: { "size" : 0, "aggs" : { "ip_range" : { "ip_range" : { "field" : "ip", "ranges": [ { "mask": "::/24" }, { "mask": "192.168.0.0/16" } ] } } } }
+
+  - match: { hits.total: 3 }
+
+  - length: { aggregations.ip_range.buckets: 2 } 
+
+  - match: { aggregations.ip_range.buckets.0.key: "::/24" }
+
+  - match: { aggregations.ip_range.buckets.0.from: "::" }
+
+  - match: { aggregations.ip_range.buckets.0.to: "0:ff:ffff:ffff:ffff:ffff:ffff:ffff" }
+
+  - match: { aggregations.ip_range.buckets.0.doc_count: 3 } 
+
+  - match: { aggregations.ip_range.buckets.1.key: "192.168.0.0/16" }
+
+  - match: { aggregations.ip_range.buckets.1.from: "192.168.0.0" }
+
+  - match: { aggregations.ip_range.buckets.1.to: "192.168.255.255" }
+
+  - match: { aggregations.ip_range.buckets.1.doc_count: 2 } 
+