From a0f7c4a6a48cec30da37f0ac773485b1130e949c Mon Sep 17 00:00:00 2001 From: Nik Everett Date: Sat, 28 Mar 2020 11:47:01 -0400 Subject: [PATCH] Clean up how pipeline aggs check for multi-bucket (#54161) Pipeline aggregations like `stats_bucket`, `sum_bucket`, and `percentiles_bucket` only operate on buckets that have multiple buckets. This adds support for those aggregations to `geo_distance`, `ip_range`, `auto_date_histogram`, and `rare_terms`. This all happened because we used a marker interface to mark compatible aggs, `MultiBucketAggregationBuilder` and it was fairly easy to forget to implement the interface. This replaces the marker interface with an abstract method in `AggregationBuilder`, `bucketCardinality` which makes you return `NONE`, `ONE`, or `MANY`. The `bucket` aggregations can check for `MANY`. At this point `ONE` and `NONE` amount to about the same thing, but I suspect that'll be a useful distinction when validating bucket sorts. Closes #53215 --- .../StringStatsAggregationBuilder.java | 5 ++ .../TopMetricsAggregationBuilder.java | 5 ++ .../stats/MatrixStatsAggregationBuilder.java | 2 +- .../ArrayValuesSourceAggregationBuilder.java | 5 ++ .../ChildrenAggregationBuilder.java | 4 + .../ParentAggregationBuilder.java | 5 ++ .../search.aggregation/280_rare_terms.yml | 61 ++++++++++++++ .../330_auto_date_histogram.yml | 73 ++++++++++++++++ .../search.aggregation/340_geo_distance.yml | 84 +++++++++++++++++++ .../test/search.aggregation/40_range.yml | 52 ++++++++++++ .../aggregations/AggregationBuilder.java | 13 +++ .../bucket/MultiBucketAggregationBuilder.java | 30 ------- .../AdjacencyMatrixAggregationBuilder.java | 9 +- .../CompositeAggregationBuilder.java | 10 +++ .../filter/FilterAggregationBuilder.java | 5 ++ .../filter/FiltersAggregationBuilder.java | 9 +- .../geogrid/GeoGridAggregationBuilder.java | 19 +++-- .../GeoHashGridAggregationBuilder.java | 6 +- .../global/GlobalAggregationBuilder.java | 5 ++ .../AutoDateHistogramAggregationBuilder.java | 21 +++-- .../DateHistogramAggregationBuilder.java | 30 ++++--- .../HistogramAggregationBuilder.java | 19 +++-- .../missing/MissingAggregationBuilder.java | 4 + .../nested/NestedAggregationBuilder.java | 5 ++ .../ReverseNestedAggregationBuilder.java | 5 ++ .../bucket/range/AbstractRangeBuilder.java | 8 +- .../range/GeoDistanceAggregationBuilder.java | 5 ++ .../range/IpRangeAggregationBuilder.java | 28 ++++--- .../DiversifiedAggregationBuilder.java | 5 ++ .../sampler/SamplerAggregationBuilder.java | 5 ++ .../SignificantTermsAggregationBuilder.java | 9 +- .../SignificantTextAggregationBuilder.java | 5 ++ .../terms/RareTermsAggregationBuilder.java | 4 + .../bucket/terms/TermsAggregationBuilder.java | 9 +- .../metrics/GeoBoundsAggregationBuilder.java | 9 +- .../ScriptedMetricAggregationBuilder.java | 5 ++ .../metrics/TopHitsAggregationBuilder.java | 5 ++ .../WeightedAvgAggregationBuilder.java | 5 ++ ...cketMetricsPipelineAggregationBuilder.java | 3 +- .../ValuesSourceAggregationBuilder.java | 5 ++ .../search/SearchModuleTests.java | 5 ++ .../StringStatsAggregationBuilder.java | 5 ++ .../TopMetricsAggregationBuilder.java | 5 ++ .../search/CancellingAggregationBuilder.java | 5 ++ .../MockDeprecatedAggregationBuilder.java | 5 ++ 45 files changed, 518 insertions(+), 103 deletions(-) create mode 100644 rest-api-spec/src/main/resources/rest-api-spec/test/search.aggregation/330_auto_date_histogram.yml create mode 100644 rest-api-spec/src/main/resources/rest-api-spec/test/search.aggregation/340_geo_distance.yml delete mode 100644 server/src/main/java/org/elasticsearch/search/aggregations/bucket/MultiBucketAggregationBuilder.java diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/analytics/StringStatsAggregationBuilder.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/analytics/StringStatsAggregationBuilder.java index 0963dacd403a2..76f8c808608a9 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/analytics/StringStatsAggregationBuilder.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/analytics/StringStatsAggregationBuilder.java @@ -89,6 +89,11 @@ protected void innerWriteTo(StreamOutput out) throws IOException { throw new UnsupportedOperationException(); } + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.NONE; + } + @Override protected ValuesSourceAggregatorFactory innerBuild(QueryShardContext queryShardContext, ValuesSourceConfig config, AggregatorFactory parent, Builder subFactoriesBuilder) throws IOException { diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/analytics/TopMetricsAggregationBuilder.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/analytics/TopMetricsAggregationBuilder.java index 24b2a5ed3a791..d520aa2794b24 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/analytics/TopMetricsAggregationBuilder.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/analytics/TopMetricsAggregationBuilder.java @@ -94,6 +94,11 @@ protected void doWriteTo(StreamOutput out) throws IOException { throw new UnsupportedOperationException(); } + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.NONE; + } + @Override protected AggregatorFactory doBuild(QueryShardContext queryShardContext, AggregatorFactory parent, Builder subfactoriesBuilder) throws IOException { diff --git a/modules/aggs-matrix-stats/src/main/java/org/elasticsearch/search/aggregations/matrix/stats/MatrixStatsAggregationBuilder.java b/modules/aggs-matrix-stats/src/main/java/org/elasticsearch/search/aggregations/matrix/stats/MatrixStatsAggregationBuilder.java index 2c94c21c4f480..cc5c7e00e7b68 100644 --- a/modules/aggs-matrix-stats/src/main/java/org/elasticsearch/search/aggregations/matrix/stats/MatrixStatsAggregationBuilder.java +++ b/modules/aggs-matrix-stats/src/main/java/org/elasticsearch/search/aggregations/matrix/stats/MatrixStatsAggregationBuilder.java @@ -34,7 +34,7 @@ import java.util.Map; public class MatrixStatsAggregationBuilder - extends ArrayValuesSourceAggregationBuilder.LeafOnly { + extends ArrayValuesSourceAggregationBuilder.LeafOnly { public static final String NAME = "matrix_stats"; private MultiValueMode multiValueMode = MultiValueMode.AVG; diff --git a/modules/aggs-matrix-stats/src/main/java/org/elasticsearch/search/aggregations/support/ArrayValuesSourceAggregationBuilder.java b/modules/aggs-matrix-stats/src/main/java/org/elasticsearch/search/aggregations/support/ArrayValuesSourceAggregationBuilder.java index b9939efc4e650..ba23e689ecc67 100644 --- a/modules/aggs-matrix-stats/src/main/java/org/elasticsearch/search/aggregations/support/ArrayValuesSourceAggregationBuilder.java +++ b/modules/aggs-matrix-stats/src/main/java/org/elasticsearch/search/aggregations/support/ArrayValuesSourceAggregationBuilder.java @@ -69,6 +69,11 @@ public AB subAggregations(Builder subFactories) { throw new AggregationInitializationException("Aggregator [" + name + "] of type [" + getType() + "] cannot accept sub-aggregations"); } + + @Override + public final BucketCardinality bucketCardinality() { + return BucketCardinality.NONE; + } } private List fields = Collections.emptyList(); diff --git a/modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/ChildrenAggregationBuilder.java b/modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/ChildrenAggregationBuilder.java index 8eedf429fa5d7..cc5cbab1296a9 100644 --- a/modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/ChildrenAggregationBuilder.java +++ b/modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/ChildrenAggregationBuilder.java @@ -97,6 +97,10 @@ protected void innerWriteTo(StreamOutput out) throws IOException { } @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.ONE; + } + protected ValuesSourceAggregatorFactory innerBuild(QueryShardContext queryShardContext, ValuesSourceConfig config, AggregatorFactory parent, diff --git a/modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/ParentAggregationBuilder.java b/modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/ParentAggregationBuilder.java index f920965e178cd..36de6f09cbc89 100644 --- a/modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/ParentAggregationBuilder.java +++ b/modules/parent-join/src/main/java/org/elasticsearch/join/aggregations/ParentAggregationBuilder.java @@ -96,6 +96,11 @@ protected void innerWriteTo(StreamOutput out) throws IOException { out.writeString(childType); } + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.ONE; + } + @Override protected ValuesSourceAggregatorFactory innerBuild(QueryShardContext queryShardContext, ValuesSourceConfig config, diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/search.aggregation/280_rare_terms.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/search.aggregation/280_rare_terms.yml index 35ed9cc0c4b7b..68139f2fe6f80 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/test/search.aggregation/280_rare_terms.yml +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/search.aggregation/280_rare_terms.yml @@ -360,3 +360,64 @@ setup: - is_false: aggregations.str_terms.buckets.0.key_as_string - match: { aggregations.str_terms.buckets.0.doc_count: 1 } - match: { aggregations.str_terms.buckets.0.max_n.value: 3.0 } + +--- +"avg_bucket": + - skip: + version: " - 7.99.99" + reason: Fixed in 8.0.0 to be backported to 7.8.0 + - do: + indices.create: + index: test + body: + settings: + number_of_replicas: 0 + mappings: + properties: + str: + type: keyword + - do: + bulk: + index: test + refresh: true + body: + - '{"index": {}}' + - '{"str": "foo", "v": 1}' + - '{"index": {}}' + - '{"str": "foo", "v": 2}' + - '{"index": {}}' + - '{"str": "foo", "v": 3}' + - '{"index": {}}' + - '{"str": "bar", "v": 4}' + - '{"index": {}}' + - '{"str": "bar", "v": 5}' + - '{"index": {}}' + - '{"str": "baz", "v": 6}' + + - do: + search: + index: test + body: + size: 0 + aggs: + str_terms: + rare_terms: + field: str + max_doc_count: 2 + aggs: + v: + sum: + field: v + str_terms_avg_v: + avg_bucket: + buckets_path: str_terms.v + + - match: { hits.total.value: 6 } + - length: { aggregations.str_terms.buckets: 2 } + - match: { aggregations.str_terms.buckets.0.key: baz } + - match: { aggregations.str_terms.buckets.0.doc_count: 1 } + - match: { aggregations.str_terms.buckets.0.v.value: 6 } + - match: { aggregations.str_terms.buckets.1.key: bar } + - match: { aggregations.str_terms.buckets.1.doc_count: 2 } + - match: { aggregations.str_terms.buckets.1.v.value: 9 } + - match: { aggregations.str_terms_avg_v.value: 7.5 } diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/search.aggregation/330_auto_date_histogram.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/search.aggregation/330_auto_date_histogram.yml new file mode 100644 index 0000000000000..15f5962b1c63c --- /dev/null +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/search.aggregation/330_auto_date_histogram.yml @@ -0,0 +1,73 @@ +setup: + - do: + indices.create: + index: test + body: + settings: + number_of_replicas: 0 + mappings: + properties: + date: + type: date + - do: + bulk: + refresh: true + index: test + body: + - '{"index": {}}' + - '{"date": "2020-03-01", "v": 1}' + - '{"index": {}}' + - '{"date": "2020-03-02", "v": 2}' + - '{"index": {}}' + - '{"date": "2020-03-08", "v": 3}' + - '{"index": {}}' + - '{"date": "2020-03-09", "v": 4}' + +--- +"basic": + - do: + search: + body: + size: 0 + aggs: + histo: + auto_date_histogram: + field: date + buckets: 2 + - match: { hits.total.value: 4 } + - length: { aggregations.histo.buckets: 2 } + - match: { aggregations.histo.buckets.0.key_as_string: "2020-03-01T00:00:00.000Z" } + - match: { aggregations.histo.buckets.0.doc_count: 2 } + - match: { aggregations.histo.buckets.1.key_as_string: "2020-03-08T00:00:00.000Z" } + - match: { aggregations.histo.buckets.1.doc_count: 2 } + +--- +"avg_bucket": + - skip: + version: " - 7.99.99" + reason: Fixed in 8.0.0 to be backported to 7.8.0 + - do: + search: + body: + size: 0 + aggs: + histo: + auto_date_histogram: + field: date + buckets: 2 + aggs: + v: + sum: + field: v + histo_avg_v: + avg_bucket: + buckets_path: histo.v + - match: { hits.total.value: 4 } + - length: { aggregations.histo.buckets: 2 } + - match: { aggregations.histo.buckets.0.key_as_string: "2020-03-01T00:00:00.000Z" } + - match: { aggregations.histo.buckets.0.doc_count: 2 } + - match: { aggregations.histo.buckets.0.v.value: 3 } + - match: { aggregations.histo.buckets.1.key_as_string: "2020-03-08T00:00:00.000Z" } + - match: { aggregations.histo.buckets.1.doc_count: 2 } + - match: { aggregations.histo.buckets.1.v.value: 7 } + - match: { aggregations.histo_avg_v.value: 5 } diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/search.aggregation/340_geo_distance.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/search.aggregation/340_geo_distance.yml new file mode 100644 index 0000000000000..4203390a08ed8 --- /dev/null +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/search.aggregation/340_geo_distance.yml @@ -0,0 +1,84 @@ +setup: + - do: + indices.create: + index: test + body: + mappings: + properties: + location: + type: geo_point + - do: + bulk: + index: test + refresh: true + body: + - '{"index": {}}' + - '{"location": {"lat" : 40.7128, "lon" : -74.0060}, "name": "New York", "population": 8623000}' + - '{"index": {}}' + - '{"location": {"lat" : 34.0522, "lon" : -118.2437}, "name": "Los Angeles", "population": 4000000}' + - '{"index": {}}' + - '{"location": {"lat" : 41.8781, "lon" : -87.6298}, "name": "Chicago", "population": 2716000}' + +--- +"basic": + - do: + search: + body: + size: 0 + aggs: + distance: + geo_distance: + field: location + origin: "35.7796, -78.6382" + ranges: + - to: 1000000 + - from: 1000000 + to: 5000000 + - from: 5000000 + - match: { hits.total.value: 3 } + - length: { aggregations.distance.buckets: 3 } + - match: { aggregations.distance.buckets.0.key: "*-1000000.0" } + - match: { aggregations.distance.buckets.0.doc_count: 1 } + - match: { aggregations.distance.buckets.1.key: "1000000.0-5000000.0" } + - match: { aggregations.distance.buckets.1.doc_count: 2 } + - match: { aggregations.distance.buckets.2.key: "5000000.0-*" } + - match: { aggregations.distance.buckets.2.doc_count: 0 } + +--- +"avg_bucket": + - skip: + version: " - 7.99.99" + reason: Fixed in 8.0.0 to be backported to 7.8.0 + - do: + search: + body: + size: 0 + aggs: + distance: + geo_distance: + field: location + origin: "35.7796, -78.6382" + ranges: + - to: 1000000 + - from: 1000000 + to: 5000000 + - from: 5000000 + aggs: + total_population: + sum: + field: population + avg_total_population: + avg_bucket: + buckets_path: distance.total_population + - match: { hits.total.value: 3 } + - length: { aggregations.distance.buckets: 3 } + - match: { aggregations.distance.buckets.0.key: "*-1000000.0" } + - match: { aggregations.distance.buckets.0.doc_count: 1 } + - match: { aggregations.distance.buckets.0.total_population.value: 8623000.0 } + - match: { aggregations.distance.buckets.1.key: "1000000.0-5000000.0" } + - match: { aggregations.distance.buckets.1.doc_count: 2 } + - match: { aggregations.distance.buckets.1.total_population.value: 6716000.0 } + - match: { aggregations.distance.buckets.2.key: "5000000.0-*" } + - match: { aggregations.distance.buckets.2.doc_count: 0 } + - match: { aggregations.distance.buckets.2.total_population.value: 0 } + - match: { aggregations.avg_total_population.value: 7669500.0 } diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/search.aggregation/40_range.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/search.aggregation/40_range.yml index 5b39730057f34..be09bab96fd33 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/test/search.aggregation/40_range.yml +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/search.aggregation/40_range.yml @@ -221,6 +221,58 @@ setup: - match: { aggregations.ip_range.buckets.1.key: "192.168.0.0-192.169.0.0" } - match: { aggregations.ip_range.buckets.2.key: "192.169.0.0-*" } +--- +"IP Range avg_bucket": + - skip: + version: " - 7.99.99" + reason: Fixed in 8.0.0 to be backported to 7.8.0 + - do: + bulk: + refresh: true + index: test + body: + - '{"index": {}}' + - '{"ip": "::1", "v": 1}' + - '{"index": {}}' + - '{"ip": "192.168.0.1", "v": 2}' + - '{"index": {}}' + - '{"ip": "192.168.0.7", "v": 3}' + + - do: + search: + index: test + body: + size: 0 + aggs: + 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 + aggs: + v: + sum: + field: v + range_avg_v: + avg_bucket: + buckets_path: range.v + + - match: { hits.total.value: 3 } + - length: { aggregations.range.buckets: 3 } + - match: { aggregations.range.buckets.0.key: "*-192.168.0.0" } + - match: { aggregations.range.buckets.0.doc_count: 1 } + - match: { aggregations.range.buckets.0.v.value: 1 } + - match: { aggregations.range.buckets.1.key: "192.168.0.0-192.169.0.0" } + - match: { aggregations.range.buckets.1.doc_count: 2 } + - match: { aggregations.range.buckets.1.v.value: 5 } + - match: { aggregations.range.buckets.2.key: "192.169.0.0-*" } + - match: { aggregations.range.buckets.2.doc_count: 0 } + - match: { aggregations.range.buckets.2.v.value: 0 } + - match: { aggregations.range_avg_v.value: 3 } + --- "Date range": - do: diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/AggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/AggregationBuilder.java index 9cf2ff4414d4c..fb5fab131d1c0 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/AggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/AggregationBuilder.java @@ -154,6 +154,19 @@ public PipelineTree buildPipelineTree() { return factoriesBuilder.buildPipelineTree(); } + /** + * Rough measure of how many buckets this aggregation can return. Just + * "zero", "one", and "many". + */ + public enum BucketCardinality { + NONE, ONE, MANY; + } + /** + * Do aggregations built by this builder contain buckets? If so, do they + * contain *always* contain a single bucket? + */ + public abstract BucketCardinality bucketCardinality(); + /** Common xcontent fields shared among aggregator builders */ public static final class CommonFields extends ParseField.CommonFields { public static final ParseField VALUE_TYPE = new ParseField("value_type"); diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/MultiBucketAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/MultiBucketAggregationBuilder.java deleted file mode 100644 index 38f3d9b0dcab9..0000000000000 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/MultiBucketAggregationBuilder.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.search.aggregations.bucket; - -import org.elasticsearch.search.aggregations.AggregationBuilder; - -/** - * Marker interface to indicate that the {@link AggregationBuilder} is for a - * multi-bucket aggregation. - */ -public interface MultiBucketAggregationBuilder { - -} diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/adjacency/AdjacencyMatrixAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/adjacency/AdjacencyMatrixAggregationBuilder.java index e6f74950fce16..7c631bdf8ad61 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/adjacency/AdjacencyMatrixAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/adjacency/AdjacencyMatrixAggregationBuilder.java @@ -34,7 +34,6 @@ import org.elasticsearch.search.aggregations.AggregationBuilder; import org.elasticsearch.search.aggregations.AggregatorFactories.Builder; import org.elasticsearch.search.aggregations.AggregatorFactory; -import org.elasticsearch.search.aggregations.bucket.MultiBucketAggregationBuilder; import org.elasticsearch.search.aggregations.bucket.adjacency.AdjacencyMatrixAggregator.KeyedFilter; import java.io.IOException; @@ -47,8 +46,7 @@ import java.util.Map.Entry; import java.util.Objects; -public class AdjacencyMatrixAggregationBuilder extends AbstractAggregationBuilder - implements MultiBucketAggregationBuilder { +public class AdjacencyMatrixAggregationBuilder extends AbstractAggregationBuilder { public static final String NAME = "adjacency_matrix"; private static final String DEFAULT_SEPARATOR = "&"; @@ -216,6 +214,11 @@ protected AggregatorFactory doBuild(QueryShardContext queryShardContext, Aggrega subFactoriesBuilder, metaData); } + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.MANY; + } + @Override protected XContentBuilder internalXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(); diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/composite/CompositeAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/composite/CompositeAggregationBuilder.java index c79cb3d05d498..b19fdffea4991 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/composite/CompositeAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/composite/CompositeAggregationBuilder.java @@ -147,6 +147,16 @@ public int size() { return size; } + @Override + public BucketCardinality bucketCardinality() { + /* + * Cardinality *does* have buckets so MULTI might be appropriate here. + * But the buckets can't be used with the composite agg so we're + * going to pretend that it doesn't have buckets. + */ + return BucketCardinality.NONE; + } + /** * Returns null if the provided factory and his parents are compatible with * this aggregator or the instance of the parent's factory that is incompatible with diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/FilterAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/FilterAggregationBuilder.java index 9f3d4b5a2ba77..f282c2113ed3c 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/FilterAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/FilterAggregationBuilder.java @@ -83,6 +83,11 @@ protected void doWriteTo(StreamOutput out) throws IOException { out.writeNamedWriteable(filter); } + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.ONE; + } + @Override protected AggregationBuilder doRewrite(QueryRewriteContext queryShardContext) throws IOException { QueryBuilder result = Rewriteable.rewrite(filter, queryShardContext); diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/FiltersAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/FiltersAggregationBuilder.java index 0125440fc4110..f9adcc9620217 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/FiltersAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/filter/FiltersAggregationBuilder.java @@ -33,7 +33,6 @@ import org.elasticsearch.search.aggregations.AggregationBuilder; import org.elasticsearch.search.aggregations.AggregatorFactories.Builder; import org.elasticsearch.search.aggregations.AggregatorFactory; -import org.elasticsearch.search.aggregations.bucket.MultiBucketAggregationBuilder; import org.elasticsearch.search.aggregations.bucket.filter.FiltersAggregator.KeyedFilter; import java.io.IOException; @@ -47,8 +46,7 @@ import static org.elasticsearch.index.query.AbstractQueryBuilder.parseInnerQueryBuilder; -public class FiltersAggregationBuilder extends AbstractAggregationBuilder - implements MultiBucketAggregationBuilder { +public class FiltersAggregationBuilder extends AbstractAggregationBuilder { public static final String NAME = "filters"; private static final ParseField FILTERS_FIELD = new ParseField("filters"); @@ -198,6 +196,11 @@ public String otherBucketKey() { return otherBucketKey; } + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.MANY; + } + @Override protected AggregationBuilder doRewrite(QueryRewriteContext queryShardContext) throws IOException { List rewrittenFilters = new ArrayList<>(filters.size()); diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/geogrid/GeoGridAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/geogrid/GeoGridAggregationBuilder.java index 88348e2545db6..f717beb64338d 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/geogrid/GeoGridAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/geogrid/GeoGridAggregationBuilder.java @@ -19,11 +19,6 @@ package org.elasticsearch.search.aggregations.bucket.geogrid; -import java.io.IOException; -import java.util.Map; -import java.util.Objects; -import java.util.function.Function; - import org.elasticsearch.ElasticsearchException; import org.elasticsearch.Version; import org.elasticsearch.common.ParseField; @@ -38,15 +33,18 @@ import org.elasticsearch.search.aggregations.AggregatorFactories.Builder; import org.elasticsearch.search.aggregations.AggregatorFactory; import org.elasticsearch.search.aggregations.bucket.BucketUtils; -import org.elasticsearch.search.aggregations.bucket.MultiBucketAggregationBuilder; import org.elasticsearch.search.aggregations.support.CoreValuesSourceType; import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder; import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory; import org.elasticsearch.search.aggregations.support.ValuesSourceConfig; import org.elasticsearch.search.aggregations.support.ValuesSourceType; -public abstract class GeoGridAggregationBuilder extends ValuesSourceAggregationBuilder - implements MultiBucketAggregationBuilder { +import java.io.IOException; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; + +public abstract class GeoGridAggregationBuilder extends ValuesSourceAggregationBuilder { /* recognized field names in JSON */ static final ParseField FIELD_PRECISION = new ParseField("precision"); static final ParseField FIELD_SIZE = new ParseField("size"); @@ -174,6 +172,11 @@ public GeoBoundingBox geoBoundingBox() { return geoBoundingBox; } + @Override + public final BucketCardinality bucketCardinality() { + return BucketCardinality.MANY; + } + @Override protected ValuesSourceAggregatorFactory innerBuild(QueryShardContext queryShardContext, ValuesSourceConfig config, diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/geogrid/GeoHashGridAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/geogrid/GeoHashGridAggregationBuilder.java index c0193e17ab245..8cf270e83b81e 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/geogrid/GeoHashGridAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/geogrid/GeoHashGridAggregationBuilder.java @@ -19,9 +19,6 @@ package org.elasticsearch.search.aggregations.bucket.geogrid; -import java.io.IOException; -import java.util.Map; - import org.elasticsearch.common.geo.GeoBoundingBox; import org.elasticsearch.common.geo.GeoUtils; import org.elasticsearch.common.io.stream.StreamInput; @@ -34,6 +31,9 @@ import org.elasticsearch.search.aggregations.support.ValuesSourceConfig; import org.elasticsearch.search.aggregations.support.ValuesSourceRegistry; +import java.io.IOException; +import java.util.Map; + public class GeoHashGridAggregationBuilder extends GeoGridAggregationBuilder { public static final String NAME = "geohash_grid"; public static final int DEFAULT_PRECISION = 5; diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/global/GlobalAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/global/GlobalAggregationBuilder.java index 12db5193c71c0..9fc1a0fb8ea06 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/global/GlobalAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/global/GlobalAggregationBuilder.java @@ -65,6 +65,11 @@ protected void doWriteTo(StreamOutput out) throws IOException { // Nothing to write } + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.ONE; + } + @Override protected AggregatorFactory doBuild(QueryShardContext queryShardContext, AggregatorFactory parent, Builder subFactoriesBuilder) throws IOException { diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/AutoDateHistogramAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/AutoDateHistogramAggregationBuilder.java index 7ed324ace5955..25e98b00b2464 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/AutoDateHistogramAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/AutoDateHistogramAggregationBuilder.java @@ -19,14 +19,6 @@ package org.elasticsearch.search.aggregations.bucket.histogram; -import static java.util.Map.entry; - -import java.io.IOException; -import java.time.ZoneId; -import java.util.Arrays; -import java.util.Map; -import java.util.Objects; - import org.elasticsearch.Version; import org.elasticsearch.common.ParseField; import org.elasticsearch.common.Rounding; @@ -47,6 +39,14 @@ import org.elasticsearch.search.aggregations.support.ValuesSourceConfig; import org.elasticsearch.search.aggregations.support.ValuesSourceType; +import java.io.IOException; +import java.time.ZoneId; +import java.util.Arrays; +import java.util.Map; +import java.util.Objects; + +import static java.util.Map.entry; + public class AutoDateHistogramAggregationBuilder extends ValuesSourceAggregationBuilder { @@ -181,6 +181,11 @@ public int getNumBuckets() { return numBuckets; } + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.MANY; + } + @Override protected ValuesSourceAggregatorFactory innerBuild(QueryShardContext queryShardContext, ValuesSourceConfig config, AggregatorFactory parent, Builder subFactoriesBuilder) throws IOException { diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/DateHistogramAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/DateHistogramAggregationBuilder.java index 3883aeae58454..5df239093c5ae 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/DateHistogramAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/DateHistogramAggregationBuilder.java @@ -19,17 +19,6 @@ package org.elasticsearch.search.aggregations.bucket.histogram; -import static java.util.Map.entry; - -import java.io.IOException; -import java.time.Instant; -import java.time.ZoneId; -import java.time.ZoneOffset; -import java.time.zone.ZoneOffsetTransition; -import java.util.List; -import java.util.Map; -import java.util.Objects; - import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.index.SortedNumericDocValues; @@ -53,7 +42,6 @@ import org.elasticsearch.search.aggregations.BucketOrder; import org.elasticsearch.search.aggregations.InternalOrder; import org.elasticsearch.search.aggregations.InternalOrder.CompoundOrder; -import org.elasticsearch.search.aggregations.bucket.MultiBucketAggregationBuilder; import org.elasticsearch.search.aggregations.support.CoreValuesSourceType; import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder; import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory; @@ -61,11 +49,22 @@ import org.elasticsearch.search.aggregations.support.ValuesSourceRegistry; import org.elasticsearch.search.aggregations.support.ValuesSourceType; +import java.io.IOException; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.zone.ZoneOffsetTransition; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import static java.util.Map.entry; + /** * A builder for histograms on date fields. */ public class DateHistogramAggregationBuilder extends ValuesSourceAggregationBuilder - implements MultiBucketAggregationBuilder, DateIntervalConsumer { + implements DateIntervalConsumer { public static final String NAME = "date_histogram"; @@ -370,6 +369,11 @@ public DateHistogramAggregationBuilder minDocCount(long minDocCount) { return this; } + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.MANY; + } + @Override protected XContentBuilder doXContentBody(XContentBuilder builder, Params params) throws IOException { diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/HistogramAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/HistogramAggregationBuilder.java index 409ca559da116..903c8ab90193d 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/HistogramAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/HistogramAggregationBuilder.java @@ -19,11 +19,6 @@ package org.elasticsearch.search.aggregations.bucket.histogram; -import java.io.IOException; -import java.util.List; -import java.util.Map; -import java.util.Objects; - import org.elasticsearch.common.ParseField; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; @@ -36,7 +31,6 @@ import org.elasticsearch.search.aggregations.BucketOrder; import org.elasticsearch.search.aggregations.InternalOrder; import org.elasticsearch.search.aggregations.InternalOrder.CompoundOrder; -import org.elasticsearch.search.aggregations.bucket.MultiBucketAggregationBuilder; import org.elasticsearch.search.aggregations.support.CoreValuesSourceType; import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder; import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory; @@ -44,12 +38,16 @@ import org.elasticsearch.search.aggregations.support.ValuesSourceRegistry; import org.elasticsearch.search.aggregations.support.ValuesSourceType; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Objects; + /** * A builder for histograms on numeric fields. This builder can operate on either base numeric fields, or numeric range fields. IP range * fields are unsupported, and will throw at the factory layer. */ -public class HistogramAggregationBuilder extends ValuesSourceAggregationBuilder - implements MultiBucketAggregationBuilder { +public class HistogramAggregationBuilder extends ValuesSourceAggregationBuilder { public static final String NAME = "histogram"; private static final ObjectParser EXTENDED_BOUNDS_PARSER = new ObjectParser<>( @@ -263,6 +261,11 @@ public HistogramAggregationBuilder minDocCount(long minDocCount) { return this; } + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.MANY; + } + @Override protected XContentBuilder doXContentBody(XContentBuilder builder, Params params) throws IOException { diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/missing/MissingAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/missing/MissingAggregationBuilder.java index d0a631240367c..0b51d1aa6de6d 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/missing/MissingAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/missing/MissingAggregationBuilder.java @@ -82,6 +82,10 @@ protected boolean serializeTargetValueType(Version version) { } @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.ONE; + } + protected ValuesSourceAggregatorFactory innerBuild(QueryShardContext queryShardContext, ValuesSourceConfig config, AggregatorFactory parent, diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/nested/NestedAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/nested/NestedAggregationBuilder.java index 593a15326af18..52a2559627c18 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/nested/NestedAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/nested/NestedAggregationBuilder.java @@ -86,6 +86,11 @@ public String path() { return path; } + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.ONE; + } + @Override protected AggregatorFactory doBuild(QueryShardContext queryShardContext, AggregatorFactory parent, diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/nested/ReverseNestedAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/nested/ReverseNestedAggregationBuilder.java index 08c0d86469e3f..043c342760387 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/nested/ReverseNestedAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/nested/ReverseNestedAggregationBuilder.java @@ -90,6 +90,11 @@ public String path() { return path; } + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.ONE; + } + @Override protected AggregatorFactory doBuild(QueryShardContext queryShardContext, AggregatorFactory parent, Builder subFactoriesBuilder) throws IOException { diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/range/AbstractRangeBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/range/AbstractRangeBuilder.java index 4e8e2acaf88fe..514474aa9169e 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/range/AbstractRangeBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/range/AbstractRangeBuilder.java @@ -25,7 +25,6 @@ import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.search.aggregations.AggregatorFactories; -import org.elasticsearch.search.aggregations.bucket.MultiBucketAggregationBuilder; import org.elasticsearch.search.aggregations.bucket.range.RangeAggregator.Range; import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder; import org.elasticsearch.search.aggregations.support.ValuesSourceType; @@ -38,7 +37,7 @@ import java.util.function.Function; public abstract class AbstractRangeBuilder, R extends Range> - extends ValuesSourceAggregationBuilder implements MultiBucketAggregationBuilder { + extends ValuesSourceAggregationBuilder { protected final InternalRange.Factory rangeFactory; protected List ranges = new ArrayList<>(); @@ -138,6 +137,11 @@ public boolean keyed() { return keyed; } + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.MANY; + } + @Override protected XContentBuilder doXContentBody(XContentBuilder builder, Params params) throws IOException { builder.field(RangeAggregator.RANGES_FIELD.getPreferredName(), ranges); diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/range/GeoDistanceAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/range/GeoDistanceAggregationBuilder.java index 0d85cebce3069..9a75e7685f5e6 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/range/GeoDistanceAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/range/GeoDistanceAggregationBuilder.java @@ -418,6 +418,11 @@ public boolean keyed() { return keyed; } + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.MANY; + } + @Override protected ValuesSourceAggregatorFactory innerBuild(QueryShardContext queryShardContext, ValuesSourceConfig config, diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/range/IpRangeAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/range/IpRangeAggregationBuilder.java index b08a50a8289d9..5ce56542c5ec5 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/range/IpRangeAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/range/IpRangeAggregationBuilder.java @@ -18,15 +18,6 @@ */ package org.elasticsearch.search.aggregations.bucket.range; -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Objects; - import org.apache.lucene.document.InetAddressPoint; import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.ParseField; @@ -51,6 +42,15 @@ import org.elasticsearch.search.aggregations.support.ValuesSourceConfig; import org.elasticsearch.search.aggregations.support.ValuesSourceType; +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; + public final class IpRangeAggregationBuilder extends ValuesSourceAggregationBuilder { @@ -362,11 +362,15 @@ private static BytesRef toBytesRef(String ip) { return new BytesRef(bytes); } + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.MANY; + } + @Override protected ValuesSourceAggregatorFactory innerBuild( - QueryShardContext queryShardContext, ValuesSourceConfig config, - AggregatorFactory parent, Builder subFactoriesBuilder) - throws IOException { + QueryShardContext queryShardContext, ValuesSourceConfig config, + AggregatorFactory parent, Builder subFactoriesBuilder) throws IOException { List ranges = new ArrayList<>(); if(this.ranges.size() == 0){ throw new IllegalArgumentException("No [ranges] specified for the [" + this.getName() + "] aggregation"); diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/sampler/DiversifiedAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/sampler/DiversifiedAggregationBuilder.java index 124e4e017dcd7..b8fbc52ab82cd 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/sampler/DiversifiedAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/sampler/DiversifiedAggregationBuilder.java @@ -146,6 +146,11 @@ public String executionHint() { return executionHint; } + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.ONE; + } + @Override protected ValuesSourceAggregatorFactory innerBuild(QueryShardContext queryShardContext, ValuesSourceConfig config, diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/sampler/SamplerAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/sampler/SamplerAggregationBuilder.java index 666d0a424a0a7..fdc73406b5e3c 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/sampler/SamplerAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/sampler/SamplerAggregationBuilder.java @@ -83,6 +83,11 @@ public int shardSize() { return shardSize; } + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.ONE; + } + @Override protected SamplerAggregatorFactory doBuild(QueryShardContext queryShardContext, AggregatorFactory parent, Builder subFactoriesBuilder) throws IOException { diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTermsAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTermsAggregationBuilder.java index 702f929a2fe2b..a511445d864a6 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTermsAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTermsAggregationBuilder.java @@ -31,7 +31,6 @@ import org.elasticsearch.search.aggregations.AggregationBuilder; import org.elasticsearch.search.aggregations.AggregatorFactories.Builder; import org.elasticsearch.search.aggregations.AggregatorFactory; -import org.elasticsearch.search.aggregations.bucket.MultiBucketAggregationBuilder; import org.elasticsearch.search.aggregations.bucket.significant.heuristics.JLHScore; import org.elasticsearch.search.aggregations.bucket.significant.heuristics.SignificanceHeuristic; import org.elasticsearch.search.aggregations.bucket.terms.IncludeExclude; @@ -51,8 +50,7 @@ import static org.elasticsearch.index.query.AbstractQueryBuilder.parseInnerQueryBuilder; -public class SignificantTermsAggregationBuilder extends ValuesSourceAggregationBuilder - implements MultiBucketAggregationBuilder { +public class SignificantTermsAggregationBuilder extends ValuesSourceAggregationBuilder { public static final String NAME = "significant_terms"; static final ParseField BACKGROUND_FILTER = new ParseField("background_filter"); @@ -289,6 +287,11 @@ public SignificanceHeuristic significanceHeuristic() { return significanceHeuristic; } + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.MANY; + } + @Override protected ValuesSourceAggregatorFactory innerBuild(QueryShardContext queryShardContext, ValuesSourceConfig config, diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTextAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTextAggregationBuilder.java index c3c6e6ea53baa..27d66900a1b0e 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTextAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTextAggregationBuilder.java @@ -321,6 +321,11 @@ protected void doWriteTo(StreamOutput out) throws IOException { out.writeOptionalStringArray(sourceFieldNames); } + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.MANY; + } + @Override protected AggregatorFactory doBuild(QueryShardContext queryShardContext, AggregatorFactory parent, Builder subFactoriesBuilder) throws IOException { diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/terms/RareTermsAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/terms/RareTermsAggregationBuilder.java index c6c1ccce246cc..762139abdbb57 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/terms/RareTermsAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/terms/RareTermsAggregationBuilder.java @@ -165,6 +165,10 @@ public void setPrecision(double precision) { } @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.MANY; + } + protected ValuesSourceAggregatorFactory innerBuild(QueryShardContext queryShardContext, ValuesSourceConfig config, AggregatorFactory parent, diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/terms/TermsAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/terms/TermsAggregationBuilder.java index 18a902f7a4dc1..158ba2d708c29 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/terms/TermsAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/terms/TermsAggregationBuilder.java @@ -34,7 +34,6 @@ import org.elasticsearch.search.aggregations.BucketOrder; import org.elasticsearch.search.aggregations.InternalOrder; import org.elasticsearch.search.aggregations.InternalOrder.CompoundOrder; -import org.elasticsearch.search.aggregations.bucket.MultiBucketAggregationBuilder; import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregator.BucketCountThresholds; import org.elasticsearch.search.aggregations.support.CoreValuesSourceType; import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder; @@ -48,8 +47,7 @@ import java.util.Map; import java.util.Objects; -public class TermsAggregationBuilder extends ValuesSourceAggregationBuilder - implements MultiBucketAggregationBuilder { +public class TermsAggregationBuilder extends ValuesSourceAggregationBuilder { public static final String NAME = "terms"; public static final ParseField EXECUTION_HINT_FIELD_NAME = new ParseField("execution_hint"); @@ -337,6 +335,11 @@ public TermsAggregationBuilder showTermDocCountError(boolean showTermDocCountErr return this; } + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.MANY; + } + @Override protected ValuesSourceAggregatorFactory innerBuild(QueryShardContext queryShardContext, ValuesSourceConfig config, diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/metrics/GeoBoundsAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/metrics/GeoBoundsAggregationBuilder.java index e7e836f547729..f21fcb8f09954 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/metrics/GeoBoundsAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/metrics/GeoBoundsAggregationBuilder.java @@ -19,10 +19,6 @@ package org.elasticsearch.search.aggregations.metrics; -import java.io.IOException; -import java.util.Map; -import java.util.Objects; - import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.xcontent.ObjectParser; @@ -104,6 +100,11 @@ public boolean wrapLongitude() { return wrapLongitude; } + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.NONE; + } + @Override protected GeoBoundsAggregatorFactory innerBuild(QueryShardContext queryShardContext, ValuesSourceConfig config, AggregatorFactory parent, Builder subFactoriesBuilder) throws IOException { diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/metrics/ScriptedMetricAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/metrics/ScriptedMetricAggregationBuilder.java index f8ec27a7d6b16..b576ff4f906ee 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/metrics/ScriptedMetricAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/metrics/ScriptedMetricAggregationBuilder.java @@ -206,6 +206,11 @@ public Map params() { return params; } + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.NONE; + } + @Override protected ScriptedMetricAggregatorFactory doBuild(QueryShardContext queryShardContext, AggregatorFactory parent, Builder subfactoriesBuilder) throws IOException { diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/metrics/TopHitsAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/metrics/TopHitsAggregationBuilder.java index d953da0346094..2290e452559ca 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/metrics/TopHitsAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/metrics/TopHitsAggregationBuilder.java @@ -570,6 +570,11 @@ public TopHitsAggregationBuilder subAggregations(Builder subFactories) { + getType() + "] cannot accept sub-aggregations"); } + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.NONE; + } + @Override protected TopHitsAggregatorFactory doBuild(QueryShardContext queryShardContext, AggregatorFactory parent, Builder subfactoriesBuilder) throws IOException { diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/metrics/WeightedAvgAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/metrics/WeightedAvgAggregationBuilder.java index 2d8548c68909e..004794ce6010c 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/metrics/WeightedAvgAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/metrics/WeightedAvgAggregationBuilder.java @@ -98,6 +98,11 @@ protected void innerWriteTo(StreamOutput out) { // Do nothing, no extra state to write to stream } + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.NONE; + } + @Override protected MultiValuesSourceAggregatorFactory innerBuild(QueryShardContext queryShardContext, Map configs, diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/pipeline/BucketMetricsPipelineAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/pipeline/BucketMetricsPipelineAggregationBuilder.java index 753f3ca38821c..e97bbb62eb60b 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/pipeline/BucketMetricsPipelineAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/pipeline/BucketMetricsPipelineAggregationBuilder.java @@ -24,7 +24,6 @@ import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.search.DocValueFormat; import org.elasticsearch.search.aggregations.AggregationBuilder; -import org.elasticsearch.search.aggregations.bucket.MultiBucketAggregationBuilder; import org.elasticsearch.search.aggregations.pipeline.BucketHelpers.GapPolicy; import java.io.IOException; @@ -121,7 +120,7 @@ protected void validate(ValidationContext context) { context.addBucketPathValidationError("aggregation does not exist for aggregation [" + name + "]: " + bucketsPaths[0]); return; } - if ((aggBuilder.get() instanceof MultiBucketAggregationBuilder) == false) { + if (aggBuilder.get().bucketCardinality() != AggregationBuilder.BucketCardinality.MANY) { context.addValidationError("The first aggregation in " + PipelineAggregator.Parser.BUCKETS_PATH.getPreferredName() + " must be a multi-bucket aggregation for aggregation [" + name + "] found :" + aggBuilder.get().getClass().getName() + " for buckets path: " + bucketsPaths[0]); diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceAggregationBuilder.java index f7bdecfa3e448..04e037163f8c5 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceAggregationBuilder.java @@ -105,6 +105,11 @@ public final AB subAggregations(Builder subFactories) { throw new AggregationInitializationException("Aggregator [" + name + "] of type [" + getType() + "] cannot accept sub-aggregations"); } + + @Override + public final BucketCardinality bucketCardinality() { + return BucketCardinality.NONE; + } } private String field = null; diff --git a/server/src/test/java/org/elasticsearch/search/SearchModuleTests.java b/server/src/test/java/org/elasticsearch/search/SearchModuleTests.java index e9ccf3c7529f6..5938c5b73a42c 100644 --- a/server/src/test/java/org/elasticsearch/search/SearchModuleTests.java +++ b/server/src/test/java/org/elasticsearch/search/SearchModuleTests.java @@ -391,6 +391,11 @@ public String getType() { protected void innerWriteTo(StreamOutput out) throws IOException { } + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.NONE; + } + @Override protected ValuesSourceAggregatorFactory innerBuild(QueryShardContext queryShardContext, ValuesSourceConfig config, diff --git a/x-pack/plugin/analytics/src/main/java/org/elasticsearch/xpack/analytics/stringstats/StringStatsAggregationBuilder.java b/x-pack/plugin/analytics/src/main/java/org/elasticsearch/xpack/analytics/stringstats/StringStatsAggregationBuilder.java index e12cd047234eb..140d71627e16e 100644 --- a/x-pack/plugin/analytics/src/main/java/org/elasticsearch/xpack/analytics/stringstats/StringStatsAggregationBuilder.java +++ b/x-pack/plugin/analytics/src/main/java/org/elasticsearch/xpack/analytics/stringstats/StringStatsAggregationBuilder.java @@ -70,6 +70,11 @@ protected void innerWriteTo(StreamOutput out) throws IOException { out.writeBoolean(showDistribution); } + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.NONE; + } + @Override protected StringStatsAggregatorFactory innerBuild(QueryShardContext queryShardContext, ValuesSourceConfig config, diff --git a/x-pack/plugin/analytics/src/main/java/org/elasticsearch/xpack/analytics/topmetrics/TopMetricsAggregationBuilder.java b/x-pack/plugin/analytics/src/main/java/org/elasticsearch/xpack/analytics/topmetrics/TopMetricsAggregationBuilder.java index 659c5ac50fb29..e8f6caf663345 100644 --- a/x-pack/plugin/analytics/src/main/java/org/elasticsearch/xpack/analytics/topmetrics/TopMetricsAggregationBuilder.java +++ b/x-pack/plugin/analytics/src/main/java/org/elasticsearch/xpack/analytics/topmetrics/TopMetricsAggregationBuilder.java @@ -113,6 +113,11 @@ protected AggregationBuilder shallowCopy(AggregatorFactories.Builder factoriesBu return new TopMetricsAggregationBuilder(this, factoriesBuilder, metaData); } + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.NONE; + } + @Override protected AggregatorFactory doBuild(QueryShardContext queryShardContext, AggregatorFactory parent, Builder subFactoriesBuilder) throws IOException { diff --git a/x-pack/plugin/async-search/src/test/java/org/elasticsearch/xpack/search/CancellingAggregationBuilder.java b/x-pack/plugin/async-search/src/test/java/org/elasticsearch/xpack/search/CancellingAggregationBuilder.java index 354c3c4ec340a..e7546155d4081 100644 --- a/x-pack/plugin/async-search/src/test/java/org/elasticsearch/xpack/search/CancellingAggregationBuilder.java +++ b/x-pack/plugin/async-search/src/test/java/org/elasticsearch/xpack/search/CancellingAggregationBuilder.java @@ -99,4 +99,9 @@ protected Aggregator createInternal(SearchContext searchContext, } }; } + + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.NONE; + } } diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/transform/transforms/MockDeprecatedAggregationBuilder.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/transform/transforms/MockDeprecatedAggregationBuilder.java index ed5a49efa487e..bde1f3d5df856 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/transform/transforms/MockDeprecatedAggregationBuilder.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/transform/transforms/MockDeprecatedAggregationBuilder.java @@ -68,6 +68,11 @@ public String getType() { protected void innerWriteTo(StreamOutput out) throws IOException { } + @Override + public BucketCardinality bucketCardinality() { + return BucketCardinality.NONE; + } + @Override protected ValuesSourceAggregatorFactory innerBuild(QueryShardContext queryShardContext, ValuesSourceConfig config,