diff --git a/src/main/java/org/elasticsearch/search/aggregations/AggregatorFactories.java b/src/main/java/org/elasticsearch/search/aggregations/AggregatorFactories.java index 87d833a398a..034155be7f8 100644 --- a/src/main/java/org/elasticsearch/search/aggregations/AggregatorFactories.java +++ b/src/main/java/org/elasticsearch/search/aggregations/AggregatorFactories.java @@ -19,6 +19,7 @@ package org.elasticsearch.search.aggregations; import org.apache.lucene.index.AtomicReaderContext; +import org.elasticsearch.ElasticsearchIllegalArgumentException; import org.elasticsearch.common.lease.Releasables; import org.elasticsearch.common.util.ObjectArray; import org.elasticsearch.search.aggregations.Aggregator.BucketAggregationMode; @@ -26,7 +27,9 @@ import org.elasticsearch.search.aggregations.support.AggregationContext; import java.io.IOException; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; /** * @@ -183,9 +186,13 @@ public class AggregatorFactories { public static class Builder { - private List factories = new ArrayList<>(); + private final Set names = new HashSet<>(); + private final List factories = new ArrayList<>(); public Builder add(AggregatorFactory factory) { + if (!names.add(factory.name)) { + throw new ElasticsearchIllegalArgumentException("Two sibling aggregations cannot have the same name: [" + factory.name + "]"); + } factories.add(factory); return this; } diff --git a/src/test/java/org/elasticsearch/search/aggregations/ParsingTests.java b/src/test/java/org/elasticsearch/search/aggregations/ParsingTests.java index 685bdca3e23..1d3044700a4 100644 --- a/src/test/java/org/elasticsearch/search/aggregations/ParsingTests.java +++ b/src/test/java/org/elasticsearch/search/aggregations/ParsingTests.java @@ -19,6 +19,7 @@ package org.elasticsearch.search.aggregations; +import com.carrotsearch.randomizedtesting.generators.RandomStrings; import org.elasticsearch.action.search.SearchPhaseExecutionException; import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.test.ElasticsearchIntegrationTest; @@ -112,6 +113,26 @@ public class ParsingTests extends ElasticsearchIntegrationTest { .endObject()).execute().actionGet(); } + @Test(expected=SearchPhaseExecutionException.class) + public void testSameAggregationName() throws Exception { + createIndex("idx"); + ensureGreen(); + final String name = RandomStrings.randomAsciiOfLength(getRandom(), 10); + client().prepareSearch("idx").setAggregations(JsonXContent.contentBuilder() + .startObject() + .startObject(name) + .startObject("terms") + .field("field", "a") + .endObject() + .endObject() + .startObject(name) + .startObject("terms") + .field("field", "b") + .endObject() + .endObject() + .endObject()).execute().actionGet(); + } + @Test(expected=SearchPhaseExecutionException.class) public void testMissingName() throws Exception { createIndex("idx");