From d88239ba632a68d58143291a2eab85fb3fbdc9f6 Mon Sep 17 00:00:00 2001 From: Adrien Grand Date: Fri, 21 Oct 2016 14:39:00 +0200 Subject: [PATCH] `ip_range` aggregation should accept null bounds. (#21043) * `ip_range` aggregation should accept null bounds. Closes #21006 * test * iter --- .../bucket/range/ip/IpRangeParser.java | 4 +- .../test/search.aggregation/40_range.yaml | 226 ++++++++++++++++++ 2 files changed, 228 insertions(+), 2 deletions(-) create mode 100644 rest-api-spec/src/main/resources/rest-api-spec/test/search.aggregation/40_range.yaml diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/range/ip/IpRangeParser.java b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/range/ip/IpRangeParser.java index 5d95f0dd494..1f4afebdbe0 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/range/ip/IpRangeParser.java +++ b/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 { diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/search.aggregation/40_range.yaml b/rest-api-spec/src/main/resources/rest-api-spec/test/search.aggregation/40_range.yaml new file mode 100644 index 00000000000..e2b6ff0e9f5 --- /dev/null +++ b/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 } +