diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java index bdd1b7e2adaba..2373765255c8f 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java @@ -1003,7 +1003,8 @@ public void testSearch() throws Exception { searchSourceBuilder.query(new TermQueryBuilder(randomAlphaOfLengthBetween(3, 10), randomAlphaOfLengthBetween(3, 10))); } if (randomBoolean()) { - searchSourceBuilder.aggregation(new TermsAggregationBuilder(randomAlphaOfLengthBetween(3, 10), ValueType.STRING) + searchSourceBuilder.aggregation(new TermsAggregationBuilder(randomAlphaOfLengthBetween(3, 10)) + .userValueTypeHint(ValueType.STRING) .field(randomAlphaOfLengthBetween(3, 10))); } if (randomBoolean()) { diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/SearchIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/SearchIT.java index 1c260d6f91ef7..06cdb27395dd5 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/SearchIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/SearchIT.java @@ -257,7 +257,8 @@ public void testSearchMatchQuery() throws IOException { public void testSearchWithTermsAgg() throws IOException { SearchRequest searchRequest = new SearchRequest(); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); - searchSourceBuilder.aggregation(new TermsAggregationBuilder("agg1", ValueType.STRING).field("type.keyword")); + searchSourceBuilder.aggregation(new TermsAggregationBuilder("agg1").userValueTypeHint(ValueType.STRING) + .field("type.keyword")); searchSourceBuilder.size(0); searchRequest.source(searchSourceBuilder); SearchResponse searchResponse = execute(searchRequest, highLevelClient()::search, highLevelClient()::searchAsync); @@ -349,7 +350,7 @@ public void testSearchWithRangeAgg() throws IOException { public void testSearchWithTermsAndRangeAgg() throws IOException { SearchRequest searchRequest = new SearchRequest("index"); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); - TermsAggregationBuilder agg = new TermsAggregationBuilder("agg1", ValueType.STRING).field("type.keyword"); + TermsAggregationBuilder agg = new TermsAggregationBuilder("agg1").userValueTypeHint(ValueType.STRING).field("type.keyword"); agg.subAggregation(new RangeAggregationBuilder("subagg").field("num") .addRange("first", 0, 30).addRange("second", 31, 200)); searchSourceBuilder.aggregation(agg); @@ -403,7 +404,7 @@ public void testSearchWithTermsAndRangeAgg() throws IOException { public void testSearchWithTermsAndWeightedAvg() throws IOException { SearchRequest searchRequest = new SearchRequest("index"); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); - TermsAggregationBuilder agg = new TermsAggregationBuilder("agg1", ValueType.STRING).field("type.keyword"); + TermsAggregationBuilder agg = new TermsAggregationBuilder("agg1").userValueTypeHint(ValueType.STRING).field("type.keyword"); agg.subAggregation(new WeightedAvgAggregationBuilder("subagg") .value(new MultiValuesSourceFieldConfig.Builder().setFieldName("num").build()) .weight(new MultiValuesSourceFieldConfig.Builder().setFieldName("num2").build()) @@ -529,10 +530,12 @@ public void testSearchWithParentJoin() throws IOException { client().performRequest(answerDoc2); client().performRequest(new Request(HttpPost.METHOD_NAME, "/_refresh")); - TermsAggregationBuilder leafTermAgg = new TermsAggregationBuilder("top-names", ValueType.STRING) + TermsAggregationBuilder leafTermAgg = new TermsAggregationBuilder("top-names") + .userValueTypeHint(ValueType.STRING) .field("owner.display_name.keyword").size(10); ChildrenAggregationBuilder childrenAgg = new ChildrenAggregationBuilder("to-answers", "answer").subAggregation(leafTermAgg); - TermsAggregationBuilder termsAgg = new TermsAggregationBuilder("top-tags", ValueType.STRING).field("tags.keyword") + TermsAggregationBuilder termsAgg = new TermsAggregationBuilder("top-tags").userValueTypeHint(ValueType.STRING) + .field("tags.keyword") .size(10).subAggregation(childrenAgg); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.size(0).aggregation(termsAgg); @@ -744,15 +747,18 @@ public void testMultiSearch() throws Exception { public void testMultiSearch_withAgg() throws Exception { MultiSearchRequest multiSearchRequest = new MultiSearchRequest(); SearchRequest searchRequest1 = new SearchRequest("index1"); - searchRequest1.source().size(0).aggregation(new TermsAggregationBuilder("name", ValueType.STRING).field("field.keyword") + searchRequest1.source().size(0).aggregation(new TermsAggregationBuilder("name").userValueTypeHint(ValueType.STRING) + .field("field.keyword") .order(BucketOrder.key(true))); multiSearchRequest.add(searchRequest1); SearchRequest searchRequest2 = new SearchRequest("index2"); - searchRequest2.source().size(0).aggregation(new TermsAggregationBuilder("name", ValueType.STRING).field("field.keyword") + searchRequest2.source().size(0).aggregation(new TermsAggregationBuilder("name").userValueTypeHint(ValueType.STRING) + .field("field.keyword") .order(BucketOrder.key(true))); multiSearchRequest.add(searchRequest2); SearchRequest searchRequest3 = new SearchRequest("index3"); - searchRequest3.source().size(0).aggregation(new TermsAggregationBuilder("name", ValueType.STRING).field("field.keyword") + searchRequest3.source().size(0).aggregation(new TermsAggregationBuilder("name").userValueTypeHint(ValueType.STRING) + .field("field.keyword") .order(BucketOrder.key(true))); multiSearchRequest.add(searchRequest3); 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 d9b36ee102268..0a19cdac3ac37 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 @@ -35,7 +35,6 @@ import org.elasticsearch.search.aggregations.AggregatorFactory; import org.elasticsearch.search.aggregations.support.CoreValuesSourceType; import org.elasticsearch.search.aggregations.support.FieldContext; -import org.elasticsearch.search.aggregations.support.ValueType; import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder; import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory; import org.elasticsearch.search.aggregations.support.ValuesSourceConfig; @@ -60,7 +59,7 @@ public class ChildrenAggregationBuilder * the type of children documents */ public ChildrenAggregationBuilder(String name, String childType) { - super(name, ValueType.STRING); + super(name); if (childType == null) { throw new IllegalArgumentException("[childType] must not be null: [" + name + "]"); } @@ -84,7 +83,7 @@ protected AggregationBuilder shallowCopy(Builder factoriesBuilder, Map verify) throws IOException { AggregationBuilder aggregationBuilder = - new TermsAggregationBuilder("subvalue_terms", ValueType.LONG).field("subNumber"). + new TermsAggregationBuilder("subvalue_terms").userValueTypeHint(ValueType.LONG).field("subNumber"). subAggregation(new ParentAggregationBuilder("to_parent", CHILD_TYPE). - subAggregation(new TermsAggregationBuilder("value_terms", ValueType.LONG).field("number"))); + subAggregation(new TermsAggregationBuilder("value_terms").userValueTypeHint(ValueType.LONG).field("number"))); MappedFieldType fieldType = new NumberFieldMapper.NumberFieldType(NumberFieldMapper.NumberType.LONG); fieldType.setName("number"); diff --git a/qa/multi-cluster-search/src/test/java/org/elasticsearch/search/CCSDuelIT.java b/qa/multi-cluster-search/src/test/java/org/elasticsearch/search/CCSDuelIT.java index a4e76fc7ec436..6bf3bc643b950 100644 --- a/qa/multi-cluster-search/src/test/java/org/elasticsearch/search/CCSDuelIT.java +++ b/qa/multi-cluster-search/src/test/java/org/elasticsearch/search/CCSDuelIT.java @@ -522,31 +522,32 @@ public void testTermsAggsWithProfile() throws Exception { private static SearchSourceBuilder buildTermsAggsSource() { SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); sourceBuilder.size(0); - TermsAggregationBuilder cluster = new TermsAggregationBuilder("cluster123", ValueType.STRING); + TermsAggregationBuilder cluster = new TermsAggregationBuilder("cluster123").userValueTypeHint(ValueType.STRING); cluster.field("_index"); - TermsAggregationBuilder type = new TermsAggregationBuilder("type", ValueType.STRING); + TermsAggregationBuilder type = new TermsAggregationBuilder("type").userValueTypeHint(ValueType.STRING); type.field("type.keyword"); type.showTermDocCountError(true); type.order(BucketOrder.key(true)); cluster.subAggregation(type); sourceBuilder.aggregation(cluster); - TermsAggregationBuilder tags = new TermsAggregationBuilder("tags", ValueType.STRING); + TermsAggregationBuilder tags = new TermsAggregationBuilder("tags").userValueTypeHint(ValueType.STRING); tags.field("tags.keyword"); tags.showTermDocCountError(true); tags.size(100); sourceBuilder.aggregation(tags); - TermsAggregationBuilder tags2 = new TermsAggregationBuilder("tags", ValueType.STRING); + TermsAggregationBuilder tags2 = new TermsAggregationBuilder("tags").userValueTypeHint(ValueType.STRING); tags2.field("tags.keyword"); tags.subAggregation(tags2); FilterAggregationBuilder answers = new FilterAggregationBuilder("answers", new TermQueryBuilder("type", "answer")); - TermsAggregationBuilder answerPerQuestion = new TermsAggregationBuilder("answer_per_question", ValueType.STRING); + TermsAggregationBuilder answerPerQuestion = new TermsAggregationBuilder("answer_per_question") + .userValueTypeHint(ValueType.STRING); answerPerQuestion.showTermDocCountError(true); answerPerQuestion.field("questionId.keyword"); answers.subAggregation(answerPerQuestion); - TermsAggregationBuilder answerPerUser = new TermsAggregationBuilder("answer_per_user", ValueType.STRING); + TermsAggregationBuilder answerPerUser = new TermsAggregationBuilder("answer_per_user").userValueTypeHint(ValueType.STRING); answerPerUser.field("user.keyword"); answerPerUser.size(30); answerPerUser.showTermDocCountError(true); @@ -561,7 +562,7 @@ public void testDateHistogram() throws Exception { SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); sourceBuilder.size(0); searchRequest.source(sourceBuilder); - TermsAggregationBuilder tags = new TermsAggregationBuilder("tags", ValueType.STRING); + TermsAggregationBuilder tags = new TermsAggregationBuilder("tags").userValueTypeHint(ValueType.STRING); tags.field("tags.keyword"); tags.showTermDocCountError(true); DateHistogramAggregationBuilder creation = new DateHistogramAggregationBuilder("creation"); @@ -578,7 +579,7 @@ public void testCardinalityAgg() throws Exception { SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); sourceBuilder.size(0); searchRequest.source(sourceBuilder); - CardinalityAggregationBuilder tags = new CardinalityAggregationBuilder("tags", ValueType.STRING); + CardinalityAggregationBuilder tags = new CardinalityAggregationBuilder("tags").userValueTypeHint(ValueType.STRING); tags.field("tags.keyword"); sourceBuilder.aggregation(tags); duelSearch(searchRequest, CCSDuelIT::assertAggs); @@ -617,7 +618,7 @@ public void testTopHits() throws Exception { topHits.size(10); topHits.sort("creationDate", SortOrder.DESC); topHits.sort("id", SortOrder.ASC); - TermsAggregationBuilder tags = new TermsAggregationBuilder("tags", ValueType.STRING); + TermsAggregationBuilder tags = new TermsAggregationBuilder("tags").userValueTypeHint(ValueType.STRING); tags.field("tags.keyword"); tags.size(10); tags.subAggregation(topHits); diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/AggregationBuilders.java b/server/src/main/java/org/elasticsearch/search/aggregations/AggregationBuilders.java index 72ac99d94b951..3b658063d17b3 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/AggregationBuilders.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/AggregationBuilders.java @@ -105,7 +105,7 @@ private AggregationBuilders() { * Create a new {@link ValueCount} aggregation with the given name. */ public static ValueCountAggregationBuilder count(String name) { - return new ValueCountAggregationBuilder(name, null); + return new ValueCountAggregationBuilder(name); } /** @@ -217,7 +217,7 @@ public static GlobalAggregationBuilder global(String name) { * Create a new {@link Missing} aggregation with the given name. */ public static MissingAggregationBuilder missing(String name) { - return new MissingAggregationBuilder(name, null); + return new MissingAggregationBuilder(name); } /** @@ -266,7 +266,7 @@ public static GeoTileGridAggregationBuilder geotileGrid(String name) { * Create a new {@link SignificantTerms} aggregation with the given name. */ public static SignificantTermsAggregationBuilder significantTerms(String name) { - return new SignificantTermsAggregationBuilder(name, null); + return new SignificantTermsAggregationBuilder(name); } @@ -313,7 +313,7 @@ public static IpRangeAggregationBuilder ipRange(String name) { * Create a new {@link Terms} aggregation with the given name. */ public static TermsAggregationBuilder terms(String name) { - return new TermsAggregationBuilder(name, null); + return new TermsAggregationBuilder(name); } /** @@ -341,7 +341,7 @@ public static MedianAbsoluteDeviationAggregationBuilder medianAbsoluteDeviation( * Create a new {@link Cardinality} aggregation with the given name. */ public static CardinalityAggregationBuilder cardinality(String name) { - return new CardinalityAggregationBuilder(name, null); + return new CardinalityAggregationBuilder(name); } /** diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/composite/CompositeValuesSourceParserHelper.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/composite/CompositeValuesSourceParserHelper.java index cf8c951a6c5de..e7b152de93266 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/composite/CompositeValuesSourceParserHelper.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/composite/CompositeValuesSourceParserHelper.java @@ -38,18 +38,18 @@ public class CompositeValuesSourceParserHelper { static , T> void declareValuesSourceFields(AbstractObjectParser objectParser, - ValueType targetValueType) { + ValueType expectedValueType) { objectParser.declareField(VB::field, XContentParser::text, new ParseField("field"), ObjectParser.ValueType.STRING); objectParser.declareBoolean(VB::missingBucket, new ParseField("missing_bucket")); objectParser.declareField(VB::valueType, p -> { ValueType valueType = ValueType.resolveForScript(p.text()); - if (targetValueType != null && valueType.isNotA(targetValueType)) { + if (expectedValueType != null && valueType.isNotA(expectedValueType)) { throw new ParsingException(p.getTokenLocation(), "Aggregation [" + objectParser.getName() + "] was configured with an incompatible value type [" - + valueType + "]. It can only work on value of type [" - + targetValueType + "]"); + + valueType + "]. It can only work on value of type [" + + expectedValueType + "]"); } return valueType; }, new ParseField("value_type"), ObjectParser.ValueType.STRING); 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 773bb8f0689c2..c03a1b7a390dd 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 @@ -31,8 +31,6 @@ 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.ValueType; import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder; import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory; import org.elasticsearch.search.aggregations.support.ValuesSourceConfig; @@ -69,7 +67,7 @@ public static ObjectParser createParser(String } public GeoGridAggregationBuilder(String name) { - super(name, ValueType.GEOPOINT); + super(name); } protected GeoGridAggregationBuilder(GeoGridAggregationBuilder clone, Builder factoriesBuilder, Map metaData) { @@ -84,7 +82,7 @@ protected GeoGridAggregationBuilder(GeoGridAggregationBuilder clone, Builder fac * Read from a stream. */ public GeoGridAggregationBuilder(StreamInput in) throws IOException { - super(in, CoreValuesSourceType.GEOPOINT, ValueType.GEOPOINT); + super(in); precision = in.readVInt(); requiredSize = in.readVInt(); shardSize = in.readVInt(); 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 e8b2a5e4981ec..347e394cc67a1 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 @@ -34,8 +34,6 @@ import org.elasticsearch.search.aggregations.AggregatorFactories.Builder; import org.elasticsearch.search.aggregations.AggregatorFactory; import org.elasticsearch.search.aggregations.MultiBucketConsumerService; -import org.elasticsearch.search.aggregations.support.CoreValuesSourceType; -import org.elasticsearch.search.aggregations.support.ValueType; import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder; import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory; import org.elasticsearch.search.aggregations.support.ValuesSourceConfig; @@ -132,12 +130,12 @@ public AutoDateHistogramAggregationBuilder setMinimumIntervalExpression(String m /** Create a new builder with the given name. */ public AutoDateHistogramAggregationBuilder(String name) { - super(name, ValueType.DATE); + super(name); } /** Read from a stream, for internal use only. */ public AutoDateHistogramAggregationBuilder(StreamInput in) throws IOException { - super(in, CoreValuesSourceType.NUMERIC, ValueType.DATE); + super(in); numBuckets = in.readVInt(); if (in.getVersion().onOrAfter(Version.V_7_3_0)) { minimumIntervalExpression = in.readOptionalString(); 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 debe6cb2c8c6b..3495187737eda 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 @@ -46,7 +46,6 @@ 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.ValueType; import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder; import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory; import org.elasticsearch.search.aggregations.support.ValuesSourceConfig; @@ -130,7 +129,7 @@ public static DateHistogramAggregationBuilder parse(String aggregationName, XCon /** Create a new builder with the given name. */ public DateHistogramAggregationBuilder(String name) { - super(name, ValueType.DATE); + super(name); } protected DateHistogramAggregationBuilder(DateHistogramAggregationBuilder clone, @@ -151,7 +150,7 @@ protected AggregationBuilder shallowCopy(Builder factoriesBuilder, Map metaData) { @@ -134,7 +132,7 @@ protected AggregationBuilder shallowCopy(Builder factoriesBuilder, Map metaData) { @@ -69,7 +67,7 @@ protected AggregationBuilder shallowCopy(Builder factoriesBuilder, Map rangeFactory) { - super(name, rangeFactory.getValueType()); + super(name); this.rangeFactory = rangeFactory; } @@ -61,12 +63,18 @@ protected AbstractRangeBuilder(AbstractRangeBuilder clone, */ protected AbstractRangeBuilder(StreamInput in, InternalRange.Factory rangeFactory, Writeable.Reader rangeReader) throws IOException { - super(in, rangeFactory.getValueSourceType(), rangeFactory.getValueType()); + super(in); this.rangeFactory = rangeFactory; ranges = in.readList(rangeReader); keyed = in.readBoolean(); } + @Override + protected ValuesSourceType defaultValueSourceType(Script script) { + // Copied over from the old targetValueType setting. Not sure what cases this is still relevant for. --Tozzi 2020-01-13 + return rangeFactory.getValueSourceType(); + } + /** * Resolve any strings in the ranges so we have a number value for the from * and to of each range. The ranges are also sorted before being returned. diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/range/DateRangeAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/range/DateRangeAggregationBuilder.java index 2741c63ea70ab..fd397ed256836 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/range/DateRangeAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/range/DateRangeAggregationBuilder.java @@ -23,12 +23,15 @@ import org.elasticsearch.common.xcontent.ObjectParser; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.index.query.QueryShardContext; +import org.elasticsearch.script.Script; import org.elasticsearch.search.DocValueFormat; import org.elasticsearch.search.aggregations.AggregationBuilder; import org.elasticsearch.search.aggregations.AggregatorFactories.Builder; import org.elasticsearch.search.aggregations.AggregatorFactory; +import org.elasticsearch.search.aggregations.support.CoreValuesSourceType; import org.elasticsearch.search.aggregations.support.ValuesSourceConfig; import org.elasticsearch.search.aggregations.support.ValuesSourceParserHelper; +import org.elasticsearch.search.aggregations.support.ValuesSourceType; import java.io.IOException; import java.time.ZonedDateTime; @@ -83,6 +86,11 @@ public String getType() { return NAME; } + @Override + protected ValuesSourceType defaultValueSourceType(Script script) { + return CoreValuesSourceType.DATE; + } + /** * Add a new range to this aggregation. * 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 fc01a41866dfe..3b5d829ef73b2 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 @@ -229,15 +229,17 @@ public GeoDistanceAggregationBuilder(String name, GeoPoint origin) { private GeoDistanceAggregationBuilder(String name, GeoPoint origin, InternalRange.Factory rangeFactory) { - super(name, rangeFactory.getValueType()); + super(name); this.origin = origin; } + // TODO: this should set defaultValuesSourceType to GEOPOINT + /** * Read from a stream. */ public GeoDistanceAggregationBuilder(StreamInput in) throws IOException { - super(in, InternalGeoDistance.FACTORY.getValueSourceType(), InternalGeoDistance.FACTORY.getValueType()); + super(in); origin = new GeoPoint(in.readDouble(), in.readDouble()); int size = in.readVInt(); ranges = new ArrayList<>(size); 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 4bb8b2169a455..81c2716564bca 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 @@ -37,11 +37,11 @@ import org.elasticsearch.search.aggregations.AggregatorFactories.Builder; import org.elasticsearch.search.aggregations.AggregatorFactory; import org.elasticsearch.search.aggregations.support.CoreValuesSourceType; -import org.elasticsearch.search.aggregations.support.ValueType; 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.ValuesSourceParserHelper; +import org.elasticsearch.search.aggregations.support.ValuesSourceType; import java.io.IOException; import java.net.InetAddress; @@ -219,7 +219,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws private List ranges = new ArrayList<>(); public IpRangeAggregationBuilder(String name) { - super(name, ValueType.IP); + super(name); } protected IpRangeAggregationBuilder(IpRangeAggregationBuilder clone, Builder factoriesBuilder, Map metaData) { @@ -336,7 +336,7 @@ public IpRangeAggregationBuilder addUnboundedFrom(String from) { } public IpRangeAggregationBuilder(StreamInput in) throws IOException { - super(in, CoreValuesSourceType.BYTES, ValueType.IP); + super(in); final int numRanges = in.readVInt(); for (int i = 0; i < numRanges; ++i) { addRange(new Range(in)); @@ -344,6 +344,11 @@ public IpRangeAggregationBuilder(StreamInput in) throws IOException { keyed = in.readBoolean(); } + @Override + protected ValuesSourceType defaultValueSourceType(Script script) { + return CoreValuesSourceType.IP; + } + @Override protected void innerWriteTo(StreamOutput out) throws IOException { out.writeVInt(ranges.size()); 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 23ef6f2bdafc5..6781f8cbb7d15 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 @@ -28,7 +28,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.support.CoreValuesSourceType; import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder; import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory; import org.elasticsearch.search.aggregations.support.ValuesSourceConfig; @@ -61,7 +60,7 @@ public static AggregationBuilder parse(String aggregationName, XContentParser pa private String executionHint = null; public DiversifiedAggregationBuilder(String name) { - super(name, null); + super(name); } protected DiversifiedAggregationBuilder(DiversifiedAggregationBuilder clone, Builder factoriesBuilder, Map metaData) { @@ -80,7 +79,7 @@ protected AggregationBuilder shallowCopy(Builder factoriesBuilder, Map metaData) { @@ -88,7 +86,7 @@ protected AggregationBuilder shallowCopy(Builder factoriesBuilder, Map metaData) { @@ -131,7 +129,7 @@ protected AggregationBuilder shallowCopy(Builder factoriesBuilder, Map metaData) { super(clone, factoriesBuilder, metaData); } + @Override + protected ValuesSourceType defaultValueSourceType(Script script) { + return CoreValuesSourceType.NUMERIC; + } + /** * Read from a stream. */ public AvgAggregationBuilder(StreamInput in) throws IOException { - super(in, CoreValuesSourceType.NUMERIC, ValueType.NUMERIC); + super(in); } @Override diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/metrics/CardinalityAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/metrics/CardinalityAggregationBuilder.java index 784e42bf0d904..4645f8f7249fa 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/metrics/CardinalityAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/metrics/CardinalityAggregationBuilder.java @@ -30,8 +30,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.support.CoreValuesSourceType; -import org.elasticsearch.search.aggregations.support.ValueType; import org.elasticsearch.search.aggregations.support.ValuesSource; import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder; import org.elasticsearch.search.aggregations.support.ValuesSourceConfig; @@ -58,13 +56,13 @@ public final class CardinalityAggregationBuilder } public static AggregationBuilder parse(String aggregationName, XContentParser parser) throws IOException { - return PARSER.parse(parser, new CardinalityAggregationBuilder(aggregationName, null), null); + return PARSER.parse(parser, new CardinalityAggregationBuilder(aggregationName), null); } private Long precisionThreshold = null; - public CardinalityAggregationBuilder(String name, ValueType targetValueType) { - super(name, CoreValuesSourceType.ANY, targetValueType); + public CardinalityAggregationBuilder(String name) { + super(name); } public CardinalityAggregationBuilder(CardinalityAggregationBuilder clone, Builder factoriesBuilder, Map metaData) { @@ -76,7 +74,7 @@ public CardinalityAggregationBuilder(CardinalityAggregationBuilder clone, Builde * Read from a stream. */ public CardinalityAggregationBuilder(StreamInput in) throws IOException { - super(in, CoreValuesSourceType.ANY); + super(in); if (in.readBoolean()) { precisionThreshold = in.readLong(); } diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/metrics/ExtendedStatsAggregationBuilder.java b/server/src/main/java/org/elasticsearch/search/aggregations/metrics/ExtendedStatsAggregationBuilder.java index 1a756d2026750..caef1bfdbda46 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/metrics/ExtendedStatsAggregationBuilder.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/metrics/ExtendedStatsAggregationBuilder.java @@ -25,15 +25,16 @@ import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.index.query.QueryShardContext; +import org.elasticsearch.script.Script; import org.elasticsearch.search.aggregations.AggregationBuilder; import org.elasticsearch.search.aggregations.AggregatorFactories.Builder; import org.elasticsearch.search.aggregations.AggregatorFactory; import org.elasticsearch.search.aggregations.support.CoreValuesSourceType; -import org.elasticsearch.search.aggregations.support.ValueType; import org.elasticsearch.search.aggregations.support.ValuesSource; import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder; import org.elasticsearch.search.aggregations.support.ValuesSourceConfig; import org.elasticsearch.search.aggregations.support.ValuesSourceParserHelper; +import org.elasticsearch.search.aggregations.support.ValuesSourceType; import java.io.IOException; import java.util.Map; @@ -57,7 +58,7 @@ public static AggregationBuilder parse(String aggregationName, XContentParser pa private double sigma = 2.0; public ExtendedStatsAggregationBuilder(String name) { - super(name, CoreValuesSourceType.NUMERIC, ValueType.NUMERIC); + super(name); } protected ExtendedStatsAggregationBuilder(ExtendedStatsAggregationBuilder clone, @@ -75,10 +76,15 @@ protected AggregationBuilder shallowCopy(Builder factoriesBuilder, Map metaData) { @@ -72,7 +73,7 @@ protected AggregationBuilder shallowCopy(Builder factoriesBuilder, Map metaData) { @@ -69,7 +67,7 @@ protected AggregationBuilder shallowCopy(Builder factoriesBuilder, Map metaData) { super(clone, factoriesBuilder, metaData); } + @Override + protected ValuesSourceType defaultValueSourceType(Script script) { + return CoreValuesSourceType.NUMERIC; + } + @Override protected AggregationBuilder shallowCopy(Builder factoriesBuilder, Map metaData) { return new MaxAggregationBuilder(this, factoriesBuilder, metaData); @@ -68,7 +74,7 @@ protected AggregationBuilder shallowCopy(Builder factoriesBuilder, Map metaData) { @@ -68,7 +69,12 @@ protected AggregationBuilder shallowCopy(Builder factoriesBuilder, Map values) { } public PercentileRanksAggregationBuilder(String name, double[] values) { - super(name, CoreValuesSourceType.NUMERIC, ValueType.NUMERIC); + super(name); if (values == null) { throw new IllegalArgumentException("[values] must not be null: [" + name + "]"); } @@ -146,7 +147,7 @@ protected AggregationBuilder shallowCopy(Builder factoriesBuilder, Map void setIfNotNull(Consumer consumer, T value) { private boolean keyed = true; public PercentilesAggregationBuilder(String name) { - super(name, CoreValuesSourceType.NUMERIC, ValueType.NUMERIC); + super(name); } protected PercentilesAggregationBuilder(PercentilesAggregationBuilder clone, @@ -153,7 +154,7 @@ protected AggregationBuilder shallowCopy(Builder factoriesBuilder, Map metaData) { @@ -68,7 +69,12 @@ protected AggregationBuilder shallowCopy(Builder factoriesBuilder, Map void declareCommon( AbstractObjectParser, T> objectParser, boolean formattable, - ValueType targetValueType) { + ValueType expectedValueType) { objectParser.declareField(MultiValuesSourceAggregationBuilder::valueType, p -> { ValueType valueType = ValueType.resolveForScript(p.text()); - if (targetValueType != null && valueType.isNotA(targetValueType)) { + if (expectedValueType != null && valueType.isNotA(expectedValueType)) { throw new ParsingException(p.getTokenLocation(), "Aggregation [" + objectParser.getName() + "] was configured with an incompatible value type [" - + valueType + "]. It can only work on value of type [" - + targetValueType + "]"); + + valueType + "]. It can only work on value off type [" + + expectedValueType + "]"); } return valueType; }, ValueType.VALUE_TYPE, ObjectParser.ValueType.STRING); diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/support/ValueType.java b/server/src/main/java/org/elasticsearch/search/aggregations/support/ValueType.java index a1e3237288fa9..bfe642caaad20 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/support/ValueType.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/support/ValueType.java @@ -37,19 +37,18 @@ public enum ValueType implements Writeable { STRING((byte) 1, "string", "string", CoreValuesSourceType.BYTES, IndexFieldData.class, DocValueFormat.RAW), - LONG((byte) 2, "byte|short|integer|long", "long", - CoreValuesSourceType.NUMERIC, - IndexNumericFieldData.class, DocValueFormat.RAW), + + LONG((byte) 2, "byte|short|integer|long", "long", CoreValuesSourceType.NUMERIC, IndexNumericFieldData.class, DocValueFormat.RAW), DOUBLE((byte) 3, "float|double", "double", CoreValuesSourceType.NUMERIC, IndexNumericFieldData.class, DocValueFormat.RAW), NUMBER((byte) 4, "number", "number", CoreValuesSourceType.NUMERIC, IndexNumericFieldData.class, DocValueFormat.RAW), - DATE((byte) 5, "date", "date", CoreValuesSourceType.NUMERIC, IndexNumericFieldData.class, + DATE((byte) 5, "date", "date", CoreValuesSourceType.DATE, IndexNumericFieldData.class, new DocValueFormat.DateTime(DateFieldMapper.DEFAULT_DATE_TIME_FORMATTER, ZoneOffset.UTC, DateFieldMapper.Resolution.MILLISECONDS)), - IP((byte) 6, "ip", "ip", CoreValuesSourceType.BYTES, IndexFieldData.class, DocValueFormat.IP), + IP((byte) 6, "ip", "ip", CoreValuesSourceType.IP, IndexFieldData.class, DocValueFormat.IP), // TODO: what is the difference between "number" and "numeric"? NUMERIC((byte) 7, "numeric", "numeric", CoreValuesSourceType.NUMERIC, IndexNumericFieldData.class, DocValueFormat.RAW), GEOPOINT((byte) 8, "geo_point", "geo_point", CoreValuesSourceType.GEOPOINT, IndexGeoPointFieldData.class, DocValueFormat.GEOHASH), - BOOLEAN((byte) 9, "boolean", "boolean", CoreValuesSourceType.NUMERIC, IndexNumericFieldData.class, DocValueFormat.BOOLEAN), + BOOLEAN((byte) 9, "boolean", "boolean", CoreValuesSourceType.BOOLEAN, IndexNumericFieldData.class, DocValueFormat.BOOLEAN), RANGE((byte) 10, "range", "range", CoreValuesSourceType.RANGE, BinaryDVIndexFieldData.class, DocValueFormat.RAW); final String description; @@ -80,8 +79,8 @@ public ValuesSourceType getValuesSourceType() { } public boolean isA(ValueType valueType) { - return valueType.valuesSourceType == valuesSourceType && - valueType.fieldDataType.isAssignableFrom(fieldDataType); + return valueType.valuesSourceType.isCastableTo(valuesSourceType) && + valueType.fieldDataType.isAssignableFrom(fieldDataType); } public boolean isNotA(ValueType valueType) { 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 a830c653df419..5195b876e2dd6 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 @@ -40,8 +40,8 @@ public abstract class ValuesSourceAggregationBuilder> extends ValuesSourceAggregationBuilder { - protected LeafOnly(String name, ValuesSourceType valuesSourceType, ValueType targetValueType) { - super(name, targetValueType); + protected LeafOnly(String name) { + super(name); } protected LeafOnly(LeafOnly clone, Builder factoriesBuilder, Map metaData) { @@ -53,18 +53,10 @@ protected LeafOnly(LeafOnly clone, Builder factoriesBuilder, Map clone, Builder factoriesBuilder, Map metaData) { super(clone, factoriesBuilder, metaData); - this.targetValueType = clone.targetValueType; this.field = clone.field; - this.valueType = clone.valueType; + this.userValueTypeHint = clone.userValueTypeHint; this.format = clone.format; this.missing = clone.missing; this.timeZone = clone.timeZone; @@ -102,34 +91,18 @@ protected ValuesSourceAggregationBuilder(ValuesSourceAggregationBuilder clon } /** - * Read an aggregation from a stream that has a sensible default for TargetValueType. This should be used by most subclasses. - * Subclasses needing to maintain backward compatibility to a version that did not serialize TargetValueType should use this - * constructor, providing the old, constant value for TargetValueType and override {@link #serializeTargetValueType(Version)} to return - * true only for versions that support the serialization. + * Read from a stream. */ - protected ValuesSourceAggregationBuilder(StreamInput in, ValuesSourceType valuesSourceType, ValueType targetValueType) + protected ValuesSourceAggregationBuilder(StreamInput in) throws IOException { super(in); if (serializeTargetValueType(in.getVersion())) { - this.targetValueType = in.readOptionalWriteable(ValueType::readFromStream); - } else { - this.targetValueType = targetValueType; + ValueType valueType = in.readOptionalWriteable(ValueType::readFromStream); + assert valueType == null; } read(in); } - /** - * Read an aggregation from a stream that serializes its targetValueType. This should only be used by subclasses that override - * {@link #serializeTargetValueType(Version)} to return true. - */ - protected ValuesSourceAggregationBuilder(StreamInput in, ValuesSourceType valuesSourceType) throws IOException { - super(in); - // TODO: Can we get rid of this constructor and always use the three value version? Does this assert provide any value? - assert serializeTargetValueType(in.getVersion()) : "Wrong read constructor called for subclass that serializes its targetValueType"; - this.targetValueType = in.readOptionalWriteable(ValueType::readFromStream); - read(in); - } - /** * Read from a stream. */ @@ -139,7 +112,7 @@ private void read(StreamInput in) throws IOException { script = new Script(in); } if (in.readBoolean()) { - valueType = ValueType.readFromStream(in); + userValueTypeHint = ValueType.readFromStream(in); } format = in.readOptionalString(); missing = in.readGenericValue(); @@ -149,7 +122,8 @@ private void read(StreamInput in) throws IOException { @Override protected final void doWriteTo(StreamOutput out) throws IOException { if (serializeTargetValueType(out.getVersion())) { - out.writeOptionalWriteable(targetValueType); + // TODO: deprecate this so we don't need to carry around a useless null in the wire format + out.writeOptionalWriteable(null); } out.writeOptionalString(field); boolean hasScript = script != null; @@ -157,10 +131,10 @@ protected final void doWriteTo(StreamOutput out) throws IOException { if (hasScript) { script.writeTo(out); } - boolean hasValueType = valueType != null; + boolean hasValueType = userValueTypeHint != null; out.writeBoolean(hasValueType); if (hasValueType) { - valueType.writeTo(out); + userValueTypeHint.writeTo(out); } out.writeOptionalString(format); out.writeGenericValue(missing); @@ -174,8 +148,10 @@ protected final void doWriteTo(StreamOutput out) throws IOException { protected abstract void innerWriteTo(StreamOutput out) throws IOException; /** - * Should this builder serialize its targetValueType? Defaults to false. All subclasses that override this to true should use the three - * argument read constructor rather than the four argument version. + * DO NOT OVERRIDE THIS! + * + * This method only exists for legacy support. No new aggregations need this, nor should they override it. + * * @param version For backwards compatibility, subclasses can change behavior based on the version */ protected boolean serializeTargetValueType(Version version) { @@ -221,22 +197,25 @@ public Script script() { } /** - * Sets the {@link ValueType} for the value produced by this aggregation + * This setter should only be used during parsing, to set the userValueTypeHint. This is information the user provides in the json + * query to indicate the output type of a script or the type of the 'missing' replacement value. + * @param valueType - The parsed {@link ValueType} based on the string the user specified + * @return - The modified builder instance, for chaining. */ @SuppressWarnings("unchecked") - public AB valueType(ValueType valueType) { + public AB userValueTypeHint(ValueType valueType) { if (valueType == null) { + // TODO: This is nonsense. We allow the value to be null (via constructor), but don't allow it to be set to null. This means + // thing looking to copy settings (like RollupRequestTranslator) need to check if userValueTypeHint is not null, and then + // set it if and only if it is non-null. throw new IllegalArgumentException("[valueType] must not be null: [" + name + "]"); } - this.valueType = valueType; + this.userValueTypeHint = valueType; return (AB) this; } - /** - * Gets the {@link ValueType} for the value produced by this aggregation - */ - public ValueType valueType() { - return valueType; + public ValueType userValueTypeHint() { + return userValueTypeHint; } /** @@ -307,30 +286,19 @@ protected final ValuesSourceAggregatorFactory doBuild(QueryShardContext querySha } /** - * Provide a hook for aggregations to have finer grained control of the CoreValuesSourceType for script values. This will only be - * called if the user did not supply a type hint for the script. The script object is provided for reference. + * Provide a hook for aggregations to have finer grained control of the {@link ValuesSourceType } when {@link ValuesSourceConfig} + * can't resolve a type (i.e. this will be called before falling back to CoreValuesSourceType.ANY.) * * @param script - The user supplied script * @return The CoreValuesSourceType we expect this script to yield. */ - protected ValuesSourceType resolveScriptAny(Script script) { + protected ValuesSourceType defaultValueSourceType(Script script) { return CoreValuesSourceType.BYTES; } - /** - * Provide a hook for aggregations to have finer grained control of the ValueType for script values. This will only be called if the - * user did not supply a type hint for the script. The script object is provided for reference - * @param script - the user supplied script - * @return The ValueType we expect this script to yield - */ - protected ValueType defaultValueType(Script script) { - return valueType; - } - protected ValuesSourceConfig resolveConfig(QueryShardContext queryShardContext) { - ValueType valueType = this.valueType != null ? this.valueType : targetValueType; return ValuesSourceConfig.resolve(queryShardContext, - valueType, field, script, missing, timeZone, format, this::resolveScriptAny, this.getType()); + this.userValueTypeHint, field, script, missing, timeZone, format, this::defaultValueSourceType, this.getType()); } protected abstract ValuesSourceAggregatorFactory innerBuild(QueryShardContext queryShardContext, @@ -356,8 +324,8 @@ public final XContentBuilder internalXContent(XContentBuilder builder, Params pa if (timeZone != null) { builder.field("time_zone", timeZone.toString()); } - if (valueType != null) { - builder.field("value_type", valueType.getPreferredName()); + if (userValueTypeHint != null) { + builder.field("value_type", userValueTypeHint.getPreferredName()); } doXContentBody(builder, params); builder.endObject(); @@ -368,8 +336,7 @@ public final XContentBuilder internalXContent(XContentBuilder builder, Params pa @Override public int hashCode() { - return Objects.hash(super.hashCode(), field, format, missing, script, - targetValueType, timeZone, valueType); + return Objects.hash(super.hashCode(), field, format, missing, script, timeZone, userValueTypeHint); } @Override @@ -382,8 +349,7 @@ public boolean equals(Object obj) { && Objects.equals(format, other.format) && Objects.equals(missing, other.missing) && Objects.equals(script, other.script) - && Objects.equals(targetValueType, other.targetValueType) && Objects.equals(timeZone, other.timeZone) - && Objects.equals(valueType, other.valueType); + && Objects.equals(userValueTypeHint, other.userValueTypeHint); } } diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceAggregatorFactory.java b/server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceAggregatorFactory.java index ac9c54399f2e0..52954afdaac9c 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceAggregatorFactory.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceAggregatorFactory.java @@ -44,28 +44,13 @@ public ValuesSourceAggregatorFactory(String name, ValuesSourceConfig config, Que @Override public Aggregator createInternal(SearchContext searchContext, Aggregator parent, boolean collectsFromSingleBucket, List pipelineAggregators, Map metaData) throws IOException { - ValuesSource vs = config.toValuesSource(queryShardContext, this::resolveMissingAny); + ValuesSource vs = config.toValuesSource(queryShardContext); if (vs == null) { return createUnmapped(searchContext, parent, pipelineAggregators, metaData); } return doCreateInternal(vs, searchContext, parent, collectsFromSingleBucket, pipelineAggregators, metaData); } - /** - * This method provides a hook for aggregations that need finer grained control over the ValuesSource selected when the user supplies a - * missing value and there is no mapped field to infer the type from. This will only be called for aggregations that specify the - * CoreValuesSourceType.ANY in their constructors (On the builder class). The user supplied object is passed as a parameter, so its - * type * may be inspected as needed. - * - * Generally, only the type of the returned ValuesSource is used, so returning the EMPTY instance of the chosen type is recommended. - * - * @param missing The user supplied missing value - * @return A ValuesSource instance compatible with the supplied parameter - */ - protected ValuesSource resolveMissingAny(Object missing) { - return ValuesSource.Bytes.WithOrdinals.EMPTY; - } - protected abstract Aggregator createUnmapped(SearchContext searchContext, Aggregator parent, List pipelineAggregators, diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceConfig.java b/server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceConfig.java index 13c6b5d5c219d..1fcd26ff195bf 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceConfig.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceConfig.java @@ -19,9 +19,7 @@ package org.elasticsearch.search.aggregations.support; import org.elasticsearch.common.Nullable; -import org.elasticsearch.common.time.DateFormatter; import org.elasticsearch.index.fielddata.IndexFieldData; -import org.elasticsearch.index.mapper.DateFieldMapper; import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.script.AggregationScript; @@ -29,7 +27,6 @@ import org.elasticsearch.search.DocValueFormat; import java.time.ZoneId; -import java.time.ZoneOffset; import java.util.function.Function; /** @@ -52,19 +49,34 @@ public static ValuesSourceConfig resolve( } /** - * Resolve a {@link ValuesSourceConfig} given configuration parameters. + * Given the query context and other information, decide on the input {@link ValuesSource} for this aggretation run, and construct a new + * {@link ValuesSourceConfig} based on that {@link ValuesSourceType} + * + * @param context - the query context + * @param userValueTypeHint - User specified value type; used for missing values and scripts + * @param field - The field being aggregated over. At least one of field and script must not be null + * @param script - The script the user specified. At least one of field and script must not be null + * @param missing - A user specified value to apply when the field is missing. Should be of type userValueTypeHint + * @param timeZone - Used to generate a format for dates + * @param format - The format string to apply to this field. Confusingly, this is used for input parsing as well as output formatting + * See https://github.com/elastic/elasticsearch/issues/47469 + * @param defaultValueSourceType - TODO: Get rid of this. + * @param aggregationName - Name of the aggregation, generally from the aggregation builder. This is used as a lookup key in the + * {@link ValuesSourceRegistry} + * @return - An initialized {@link ValuesSourceConfig} that will yield the appropriate {@link ValuesSourceType} */ public static ValuesSourceConfig resolve( QueryShardContext context, - ValueType valueType, + ValueType userValueTypeHint, String field, Script script, Object missing, ZoneId timeZone, String format, - Function resolveScriptAny, + Function defaultValueSourceType, String aggregationName) { ValuesSourceConfig config; - + MappedFieldType fieldType = null; + ValuesSourceType valuesSourceType; if (field == null) { // Stand Alone Script Case if (script == null) { @@ -73,25 +85,20 @@ public static ValuesSourceConfig resolve( } /* * This is the Stand Alone Script path. We should have a script that will produce a value independent of the presence or - * absence of any one field. The type of the script is given by the valueType field, and defaults to bytes if not specified. + * absence of any one field. The type of the script is given by the userValueTypeHint field, if the user specified a type, + * or the aggregation's default type if the user didn't. */ - // TODO: Not pluggable, should always be valueType if specified, BYTES if not. - // TODO: Probably should validate that the resulting type is valid for this agg. That needs to be plugable. - ValuesSourceType valuesSourceType = valueType != null ? valueType.getValuesSourceType() : CoreValuesSourceType.ANY; - if (valuesSourceType == CoreValuesSourceType.ANY) { - // the specific value source type is undefined, but for scripts, - // we need to have a specific value source - // type to know how to handle the script values, so we fallback - // on Bytes - valuesSourceType = resolveScriptAny.apply(script); + if (userValueTypeHint != null) { + valuesSourceType = userValueTypeHint.getValuesSourceType(); + } else { + valuesSourceType = defaultValueSourceType.apply(script); } config = new ValuesSourceConfig(valuesSourceType); - config.format(resolveFormat(format, valueType, timeZone)); config.script(createScript(script, context)); - config.scriptValueType(valueType); + config.scriptValueType(userValueTypeHint); } else { // Field case - MappedFieldType fieldType = context.fieldMapper(field); + fieldType = context.fieldMapper(field); if (fieldType == null) { /* Unmapped Field Case * We got here because the user specified a field, but it doesn't exist on this index, possibly because of a wildcard index @@ -99,25 +106,30 @@ public static ValuesSourceConfig resolve( * specified missing value. */ // TODO: This should be pluggable too; Effectively that will replace the missingAny() case from toValuesSource() - ValuesSourceType valuesSourceType = valueType != null ? valueType.getValuesSourceType() : CoreValuesSourceType.ANY; - config = new ValuesSourceConfig(valuesSourceType); - config.format(resolveFormat(format, valueType, timeZone)); + if (userValueTypeHint != null) { + valuesSourceType = userValueTypeHint.getValuesSourceType(); + } else { + valuesSourceType = defaultValueSourceType.apply(script); + } + config = new ValuesSourceConfig(valuesSourceType); + // TODO: PLAN - get rid of the unmapped flag field; it's only used by valid(), and we're intending to get rid of that. + // TODO: Once we no longer care about unmapped, we can merge this case with the mapped case. config.unmapped(true); - if (valueType != null) { + if (userValueTypeHint != null) { // todo do we really need this for unmapped? - config.scriptValueType(valueType); + config.scriptValueType(userValueTypeHint); } } else { IndexFieldData indexFieldData = context.getForField(fieldType); - ValuesSourceType valuesSourceType = ValuesSourceRegistry.getInstance().getValuesSourceType(fieldType, indexFieldData, - aggregationName, valueType); + valuesSourceType = ValuesSourceRegistry.getInstance().getValuesSourceType(fieldType, indexFieldData, + aggregationName, userValueTypeHint, script, defaultValueSourceType); config = new ValuesSourceConfig(valuesSourceType); config.fieldContext(new FieldContext(field, indexFieldData, fieldType)); config.script(createScript(script, context)); - config.format(fieldType.docValueFormat(format, timeZone)); } } + config.format(resolveFormat(format, valuesSourceType, timeZone, fieldType)); config.missing(missing); config.timezone(timeZone); return config; @@ -132,19 +144,13 @@ private static AggregationScript.LeafFactory createScript(Script script, QuerySh } } - private static DocValueFormat resolveFormat(@Nullable String format, @Nullable ValueType valueType, @Nullable ZoneId tz) { - if (valueType == null) { - return DocValueFormat.RAW; // we can't figure it out + private static DocValueFormat resolveFormat(@Nullable String format, @Nullable ValuesSourceType valuesSourceType, @Nullable ZoneId tz, + MappedFieldType fieldType) { + if (fieldType != null) { + return fieldType.docValueFormat(format, tz); } - DocValueFormat valueFormat = valueType.defaultFormat; - if (valueFormat instanceof DocValueFormat.Decimal && format != null) { - valueFormat = new DocValueFormat.Decimal(format); - } - if (valueFormat instanceof DocValueFormat.DateTime && format != null) { - valueFormat = new DocValueFormat.DateTime(DateFormatter.forPattern(format), tz != null ? tz : ZoneOffset.UTC, - DateFieldMapper.Resolution.MILLISECONDS); - } - return valueFormat; + // Script or Unmapped case + return valuesSourceType.getFormatter(format, tz); } private final ValuesSourceType valueSourceType; @@ -231,15 +237,14 @@ public DocValueFormat format() { return format; } + /** + * Transform the {@link ValuesSourceType} we selected in resolve into the specific {@link ValuesSource} instance to use for this shard + * @param context - Literally just used to get the current time + * @return - A {@link ValuesSource} ready to be read from by an aggregator + */ @Nullable + // TODO: Replace QueryShardContext with a LongProvider public ValuesSource toValuesSource(QueryShardContext context) { - return toValuesSource(context, value -> ValuesSource.Bytes.WithOrdinals.EMPTY); - } - - /** Get a value source given its configuration. A return value of null indicates that - * no value source could be built. */ - @Nullable - public ValuesSource toValuesSource(QueryShardContext context, Function resolveMissingAny) { if (!valid()) { // TODO: resolve no longer generates invalid configs. Once VSConfig is immutable, we can drop this check throw new IllegalStateException( @@ -251,9 +256,6 @@ public ValuesSource toValuesSource(QueryShardContext context, Function void declareGeoFields( private static void declareFields( AbstractObjectParser, T> objectParser, - boolean scriptable, boolean formattable, boolean timezoneAware, ValueType targetValueType) { + boolean scriptable, boolean formattable, boolean timezoneAware, ValueType expectedInputType) { objectParser.declareField(ValuesSourceAggregationBuilder::field, XContentParser::text, @@ -74,13 +74,13 @@ private static void declareFields( objectParser.declareField(ValuesSourceAggregationBuilder::missing, XContentParser::objectText, ParseField.CommonFields.MISSING, ObjectParser.ValueType.VALUE); - objectParser.declareField(ValuesSourceAggregationBuilder::valueType, p -> { + objectParser.declareField(ValuesSourceAggregationBuilder::userValueTypeHint, p -> { ValueType valueType = ValueType.resolveForScript(p.text()); - if (targetValueType != null && valueType.isNotA(targetValueType)) { + if (expectedInputType != null && valueType.isNotA(expectedInputType)) { throw new ParsingException(p.getTokenLocation(), - "Aggregation [" + objectParser.getName() + "] was configured with an incompatible value type [" - + valueType + "]. It can only work on value of type [" - + targetValueType + "]"); + "Aggregation [" + objectParser.getName() + "] was configured with an incompatible value type [" + + valueType + "]. It can only work on value off type [" + + expectedInputType + "]"); } return valueType; }, ValueType.VALUE_TYPE, ObjectParser.ValueType.STRING); diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceRegistry.java b/server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceRegistry.java index b24edafba7468..ba5ee2587ab92 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceRegistry.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceRegistry.java @@ -24,6 +24,7 @@ import org.elasticsearch.index.fielddata.IndexNumericFieldData; import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.RangeFieldMapper; +import org.elasticsearch.script.Script; import org.elasticsearch.search.aggregations.AggregationExecutionException; import java.util.AbstractMap; @@ -31,6 +32,7 @@ import java.util.Map; import java.util.StringJoiner; import java.util.function.BiFunction; +import java.util.function.Function; /* This is a _very_ crude prototype for the ValuesSourceRegistry which basically hard-codes everything. The intent is to define the API @@ -106,7 +108,8 @@ public AggregatorSupplier getAggregator(ValuesSourceType valuesSourceType, Strin @Override public ValuesSourceType getValuesSourceType(MappedFieldType fieldType, IndexFieldData indexFieldData, String aggregationName, - ValueType valueType) { + ValueType valueType, Script script, + Function defaultValuesSourceType) { if (aggregationName != null && resolverRegistry.containsKey(aggregationName)) { List, ValuesSourceType>> resolverList = resolverRegistry.get(aggregationName); @@ -132,7 +135,7 @@ public ValuesSourceType getValuesSourceType(MappedFieldType fieldType, IndexFiel return CoreValuesSourceType.HISTOGRAM; } else { if (valueType == null) { - return CoreValuesSourceType.BYTES; + return defaultValuesSourceType.apply(script); } else { return valueType.getValuesSourceType(); } @@ -157,7 +160,8 @@ public abstract void register(String aggregationName, ValuesSourceType valuesSou public abstract AggregatorSupplier getAggregator(ValuesSourceType valuesSourceType, String aggregationName); // TODO: ValueType argument is only needed for legacy logic public abstract ValuesSourceType getValuesSourceType(MappedFieldType fieldType, IndexFieldData indexFieldData, String aggregationName, - ValueType valueType); + ValueType valueType, Script script, + Function defaultValuesSourceType); public static ValuesSourceRegistry getInstance() {return INSTANCE;} diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceType.java b/server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceType.java index 52f39cfe9326f..d18438827bbc4 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceType.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/support/ValuesSourceType.java @@ -22,6 +22,7 @@ import org.elasticsearch.script.AggregationScript; import org.elasticsearch.search.DocValueFormat; +import java.time.ZoneId; import java.util.function.LongSupplier; /** @@ -70,4 +71,21 @@ public interface ValuesSourceType { */ ValuesSource replaceMissing(ValuesSource valuesSource, Object rawMissing, DocValueFormat docValueFormat, LongSupplier now); + + /** + * This method provides a hook for specifying a type-specific formatter. When {@link ValuesSourceConfig} can resolve a + * {@link org.elasticsearch.index.mapper.MappedFieldType}, it prefers to get the formatter from there. Only when a field can't be + * resolved (which is to say script cases and unmapped field cases), it will fall back to calling this method on whatever + * {@link ValuesSourceType} it was able to resolve to. + * + * @param format - User supplied format string (Optional) + * @param tz - User supplied time zone (Optional) + * @return - A formatter object, configured with the passed in settings if appropriate. + */ + default DocValueFormat getFormatter(String format, ZoneId tz) { + return DocValueFormat.RAW; + } + + // TODO: This is scaffolding to shore up the parser logic while we're still refactoring. Don't merge this to master + boolean isCastableTo(ValuesSourceType valuesSourceType); } diff --git a/server/src/test/java/org/elasticsearch/action/search/TransportSearchActionSingleNodeTests.java b/server/src/test/java/org/elasticsearch/action/search/TransportSearchActionSingleNodeTests.java index 10f252c30dc3b..7e27aaac59ecb 100644 --- a/server/src/test/java/org/elasticsearch/action/search/TransportSearchActionSingleNodeTests.java +++ b/server/src/test/java/org/elasticsearch/action/search/TransportSearchActionSingleNodeTests.java @@ -150,7 +150,7 @@ public void testFinalReduce() { SearchSourceBuilder source = new SearchSourceBuilder(); source.size(0); originalRequest.source(source); - TermsAggregationBuilder terms = new TermsAggregationBuilder("terms", ValueType.NUMERIC); + TermsAggregationBuilder terms = new TermsAggregationBuilder("terms").userValueTypeHint(ValueType.NUMERIC); terms.field("price"); terms.size(1); source.aggregation(terms); diff --git a/server/src/test/java/org/elasticsearch/search/SearchModuleTests.java b/server/src/test/java/org/elasticsearch/search/SearchModuleTests.java index 398ddc4a1506c..6e388a3b5ca87 100644 --- a/server/src/test/java/org/elasticsearch/search/SearchModuleTests.java +++ b/server/src/test/java/org/elasticsearch/search/SearchModuleTests.java @@ -372,7 +372,7 @@ protected AggregationBuilder shallowCopy(Builder factoriesBuilder, Map @Override protected TermsAggregationBuilder createTestAggregatorBuilder() { String name = randomAlphaOfLengthBetween(3, 20); - TermsAggregationBuilder factory = new TermsAggregationBuilder(name, null); + TermsAggregationBuilder factory = new TermsAggregationBuilder(name); String field = randomAlphaOfLengthBetween(3, 20); randomFieldOrScript(factory, field); if (randomBoolean()) { diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/bucket/composite/CompositeAggregatorTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/bucket/composite/CompositeAggregatorTests.java index 7769dee3c5833..21298679f918a 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/bucket/composite/CompositeAggregatorTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/bucket/composite/CompositeAggregatorTests.java @@ -1625,7 +1625,7 @@ public void testWithTermsSubAggExecutionMode() throws Exception { .field("keyword"); return new CompositeAggregationBuilder("name", Collections.singletonList(terms)) .subAggregation( - new TermsAggregationBuilder("terms", ValueType.STRING) + new TermsAggregationBuilder("terms").userValueTypeHint(ValueType.STRING) .field("terms") .collectMode(mode) .subAggregation(new MaxAggregationBuilder("max").field("long")) @@ -1653,7 +1653,7 @@ public void testWithTermsSubAggExecutionMode() throws Exception { .field("keyword"); return new CompositeAggregationBuilder("name", Collections.singletonList(terms)) .subAggregation( - new TermsAggregationBuilder("terms", ValueType.STRING) + new TermsAggregationBuilder("terms").userValueTypeHint(ValueType.STRING) .field("terms") .collectMode(mode) .subAggregation(new MaxAggregationBuilder("max").field("long")) diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/bucket/missing/MissingAggregatorTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/bucket/missing/MissingAggregatorTests.java index dbc3ac3b490c2..a42ddbbad9375 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/bucket/missing/MissingAggregatorTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/bucket/missing/MissingAggregatorTests.java @@ -177,7 +177,7 @@ private void executeTestCase(int numDocs, try (IndexReader indexReader = DirectoryReader.open(directory)) { IndexSearcher indexSearcher = newSearcher(indexReader, true, true); - MissingAggregationBuilder builder = new MissingAggregationBuilder("_name", null); + MissingAggregationBuilder builder = new MissingAggregationBuilder("_name"); builder.field(fieldName); InternalMissing missing; diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/bucket/nested/NestedAggregatorTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/bucket/nested/NestedAggregatorTests.java index 4983575860f86..f7c473f5fa8df 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/bucket/nested/NestedAggregatorTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/bucket/nested/NestedAggregatorTests.java @@ -416,7 +416,7 @@ public void testNestedOrdering() throws IOException { fieldType2.setHasDocValues(true); fieldType2.setName("author"); - TermsAggregationBuilder termsBuilder = new TermsAggregationBuilder("authors", ValueType.STRING) + TermsAggregationBuilder termsBuilder = new TermsAggregationBuilder("authors").userValueTypeHint(ValueType.STRING) .field("author").order(BucketOrder.aggregation("chapters>num_pages.value", true)); NestedAggregationBuilder nestedBuilder = new NestedAggregationBuilder("chapters", "nested_chapters"); MaxAggregationBuilder maxAgg = new MaxAggregationBuilder("num_pages").field("num_pages"); @@ -465,7 +465,7 @@ public void testNestedOrdering() throws IOException { assertEquals(70, (int) numPages.getValue()); // reverse order: - termsBuilder = new TermsAggregationBuilder("authors", ValueType.STRING) + termsBuilder = new TermsAggregationBuilder("authors").userValueTypeHint(ValueType.STRING) .field("author").order(BucketOrder.aggregation("chapters>num_pages.value", false)); nestedBuilder = new NestedAggregationBuilder("chapters", "nested_chapters"); maxAgg = new MaxAggregationBuilder("num_pages").field("num_pages"); @@ -554,7 +554,7 @@ public void testNestedOrdering_random() throws IOException { fieldType2.setHasDocValues(true); fieldType2.setName("author"); - TermsAggregationBuilder termsBuilder = new TermsAggregationBuilder("authors", ValueType.STRING) + TermsAggregationBuilder termsBuilder = new TermsAggregationBuilder("authors").userValueTypeHint(ValueType.STRING) .size(books.size()).field("author") .order(BucketOrder.compound(BucketOrder.aggregation("chapters>num_pages.value", true), BucketOrder.key(true))); NestedAggregationBuilder nestedBuilder = new NestedAggregationBuilder("chapters", "nested_chapters"); @@ -646,8 +646,10 @@ public void testPreGetChildLeafCollectors() throws IOException { iw.commit(); } try (IndexReader indexReader = wrap(DirectoryReader.open(directory))) { - TermsAggregationBuilder valueBuilder = new TermsAggregationBuilder("value", ValueType.STRING).field("value"); - TermsAggregationBuilder keyBuilder = new TermsAggregationBuilder("key", ValueType.STRING).field("key"); + TermsAggregationBuilder valueBuilder = new TermsAggregationBuilder("value").userValueTypeHint(ValueType.STRING) + .field("value"); + TermsAggregationBuilder keyBuilder = new TermsAggregationBuilder("key").userValueTypeHint(ValueType.STRING) + .field("key"); keyBuilder.subAggregation(valueBuilder); NestedAggregationBuilder nestedBuilder = new NestedAggregationBuilder(NESTED_AGG, "nested_field"); nestedBuilder.subAggregation(keyBuilder); @@ -763,7 +765,7 @@ public void testNestedWithPipeline() throws IOException { } try (IndexReader indexReader = wrap(DirectoryReader.open(directory))) { NestedAggregationBuilder nestedBuilder = new NestedAggregationBuilder(NESTED_AGG, NESTED_OBJECT) - .subAggregation(new TermsAggregationBuilder("terms", ValueType.NUMERIC).field(VALUE_FIELD_NAME) + .subAggregation(new TermsAggregationBuilder("terms").field(VALUE_FIELD_NAME).userValueTypeHint(ValueType.NUMERIC) .subAggregation(new MaxAggregationBuilder(MAX_AGG_NAME).field(VALUE_FIELD_NAME)) .subAggregation(new BucketScriptPipelineAggregationBuilder("bucketscript", Collections.singletonMap("_value", MAX_AGG_NAME), diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/bucket/sampler/DiversifiedSamplerTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/bucket/sampler/DiversifiedSamplerTests.java index 5c29aabfa9dc4..d9ebbf633f242 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/bucket/sampler/DiversifiedSamplerTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/bucket/sampler/DiversifiedSamplerTests.java @@ -201,7 +201,7 @@ private void testCase(IndexSearcher indexSearcher, MappedFieldType genreFieldTyp .executionHint(executionHint) .maxDocsPerValue(maxDocsPerValue) .shardSize(shardSize) - .subAggregation(new TermsAggregationBuilder("terms", null).field("id")); + .subAggregation(new TermsAggregationBuilder("terms").field("id")); InternalSampler result = search(indexSearcher, query, builder, genreFieldType, idFieldType); verify.accept(result); @@ -224,7 +224,7 @@ public void testDiversifiedSampler_noDocs() throws Exception { DiversifiedAggregationBuilder builder = new DiversifiedAggregationBuilder("_name") .field(genreFieldType.name()) - .subAggregation(new TermsAggregationBuilder("terms", null).field("id")); + .subAggregation(new TermsAggregationBuilder("terms").field("id")); InternalSampler result = search(indexSearcher, new MatchAllDocsQuery(), builder, genreFieldType, idFieldType); Terms terms = result.getAggregations().get("terms"); diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTermsAggregatorTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTermsAggregatorTests.java index 6cb4826ead2c4..120e5cc00252e 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTermsAggregatorTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/bucket/significant/SignificantTermsAggregatorTests.java @@ -101,14 +101,14 @@ public void testSignificance() throws IOException { try (Directory dir = newDirectory(); IndexWriter w = new IndexWriter(dir, indexWriterConfig)) { addMixedTextDocs(textFieldType, w); - SignificantTermsAggregationBuilder sigAgg = new SignificantTermsAggregationBuilder("sig_text", null).field("text"); + SignificantTermsAggregationBuilder sigAgg = new SignificantTermsAggregationBuilder("sig_text").field("text"); sigAgg.executionHint(randomExecutionHint()); if (randomBoolean()) { // Use a background filter which just happens to be same scope as whole-index. sigAgg.backgroundFilter(QueryBuilders.termsQuery("text", "common")); } - SignificantTermsAggregationBuilder sigNumAgg = new SignificantTermsAggregationBuilder("sig_number", null).field("long_field"); + SignificantTermsAggregationBuilder sigNumAgg = new SignificantTermsAggregationBuilder("sig_number").field("long_field"); sigNumAgg.executionHint(randomExecutionHint()); try (IndexReader reader = DirectoryReader.open(w)) { @@ -200,7 +200,7 @@ public void testNumericSignificance() throws IOException { w.addDocument(doc); } - SignificantTermsAggregationBuilder sigNumAgg = new SignificantTermsAggregationBuilder("sig_number", null).field("long_field"); + SignificantTermsAggregationBuilder sigNumAgg = new SignificantTermsAggregationBuilder("sig_number").field("long_field"); sigNumAgg.executionHint(randomExecutionHint()); try (IndexReader reader = DirectoryReader.open(w)) { @@ -242,7 +242,7 @@ public void testUnmapped() throws IOException { addMixedTextDocs(textFieldType, w); // Attempt aggregation on unmapped field - SignificantTermsAggregationBuilder sigAgg = new SignificantTermsAggregationBuilder("sig_text", null).field("unmapped_field"); + SignificantTermsAggregationBuilder sigAgg = new SignificantTermsAggregationBuilder("sig_text").field("unmapped_field"); sigAgg.executionHint(randomExecutionHint()); try (IndexReader reader = DirectoryReader.open(w)) { @@ -289,7 +289,7 @@ public void testRangeField() throws IOException { } // Attempt aggregation on range field - SignificantTermsAggregationBuilder sigAgg = new SignificantTermsAggregationBuilder("sig_text", null).field(fieldName); + SignificantTermsAggregationBuilder sigAgg = new SignificantTermsAggregationBuilder("sig_text").field(fieldName); sigAgg.executionHint(randomExecutionHint()); try (IndexReader reader = DirectoryReader.open(w)) { diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/bucket/terms/RareTermsAggregatorTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/bucket/terms/RareTermsAggregatorTests.java index 441ed43d244d2..3d2fc82049693 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/bucket/terms/RareTermsAggregatorTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/bucket/terms/RareTermsAggregatorTests.java @@ -273,7 +273,8 @@ public void testUnmapped() throws Exception { ValueType[] valueTypes = new ValueType[]{ValueType.STRING, ValueType.LONG}; String[] fieldNames = new String[]{"string", "long"}; for (int i = 0; i < fieldNames.length; i++) { - RareTermsAggregationBuilder aggregationBuilder = new RareTermsAggregationBuilder("_name", valueTypes[i]) + RareTermsAggregationBuilder aggregationBuilder = new RareTermsAggregationBuilder("_name") + .userValueTypeHint(valueTypes[i]) .field(fieldNames[i]); Aggregator aggregator = createAggregator(aggregationBuilder, indexSearcher, fieldType1, fieldType2); aggregator.preCollection(); @@ -308,7 +309,7 @@ public void testRangeField() throws Exception { try (IndexReader indexReader = maybeWrapReaderEs(indexWriter.getReader())) { IndexSearcher indexSearcher = newIndexSearcher(indexReader); - RareTermsAggregationBuilder aggregationBuilder = new RareTermsAggregationBuilder("_name", null) + RareTermsAggregationBuilder aggregationBuilder = new RareTermsAggregationBuilder("_name") .field("field"); expectThrows(AggregationExecutionException.class, () -> createAggregator(aggregationBuilder, indexSearcher, fieldType)); @@ -322,7 +323,8 @@ public void testNestedTerms() throws IOException { Query query = new MatchAllDocsQuery(); testBothCases(query, dataset, aggregation -> { - TermsAggregationBuilder terms = new TermsAggregationBuilder("the_terms", ValueType.STRING).field(KEYWORD_FIELD); + TermsAggregationBuilder terms = new TermsAggregationBuilder("the_terms").userValueTypeHint(ValueType.STRING) + .field(KEYWORD_FIELD); aggregation.field(LONG_FIELD).maxDocCount(1).subAggregation(terms); }, agg -> { @@ -340,7 +342,8 @@ public void testNestedTerms() throws IOException { ); testBothCases(query, dataset, aggregation -> { - TermsAggregationBuilder terms = new TermsAggregationBuilder("the_terms", ValueType.STRING).field(KEYWORD_FIELD); + TermsAggregationBuilder terms = new TermsAggregationBuilder("the_terms").userValueTypeHint(ValueType.STRING) + .field(KEYWORD_FIELD); aggregation.field(KEYWORD_FIELD).maxDocCount(1).subAggregation(terms); }, agg -> { @@ -375,10 +378,12 @@ public void testGlobalAggregationWithScore() throws IOException { Aggregator.SubAggCollectionMode collectionMode = randomFrom(Aggregator.SubAggCollectionMode.values()); GlobalAggregationBuilder globalBuilder = new GlobalAggregationBuilder("global") .subAggregation( - new RareTermsAggregationBuilder("terms", ValueType.STRING) + new RareTermsAggregationBuilder("terms") + .userValueTypeHint(ValueType.STRING) .field("keyword") .subAggregation( - new RareTermsAggregationBuilder("sub_terms", ValueType.STRING) + new RareTermsAggregationBuilder("sub_terms") + .userValueTypeHint(ValueType.STRING) .field("keyword") .subAggregation( new TopHitsAggregationBuilder("top_hits") @@ -422,7 +427,8 @@ public void testWithNestedAggregations() throws IOException { indexWriter.commit(); NestedAggregationBuilder nested = new NestedAggregationBuilder("nested", "nested_object") - .subAggregation(new RareTermsAggregationBuilder("terms", ValueType.LONG) + .subAggregation(new RareTermsAggregationBuilder("terms") + .userValueTypeHint(ValueType.LONG) .field("nested_value") .maxDocCount(1) ); @@ -455,7 +461,8 @@ public void testWithNestedScoringAggregations() throws IOException { indexWriter.commit(); for (boolean withScore : new boolean[]{true, false}) { NestedAggregationBuilder nested = new NestedAggregationBuilder("nested", "nested_object") - .subAggregation(new RareTermsAggregationBuilder("terms", ValueType.LONG) + .subAggregation(new RareTermsAggregationBuilder("terms") + .userValueTypeHint(ValueType.LONG) .field("nested_value") .maxDocCount(2) .subAggregation( @@ -578,7 +585,8 @@ private void executeTestCase(boolean reduced, Query query, List dataset, try (IndexReader indexReader = DirectoryReader.open(directory)) { IndexSearcher indexSearcher = newIndexSearcher(indexReader); - RareTermsAggregationBuilder aggregationBuilder = new RareTermsAggregationBuilder("_name", valueType); + RareTermsAggregationBuilder aggregationBuilder = new RareTermsAggregationBuilder("_name"); + aggregationBuilder.userValueTypeHint(valueType); if (configure != null) { configure.accept(aggregationBuilder); } diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/bucket/terms/TermsAggregatorTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/bucket/terms/TermsAggregatorTests.java index 611e7d916c9c9..b4aedb3061f0b 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/bucket/terms/TermsAggregatorTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/bucket/terms/TermsAggregatorTests.java @@ -132,7 +132,7 @@ public void testGlobalOrdinalsExecutionHint() throws Exception { // We do not use LuceneTestCase.newSearcher because we need a DirectoryReader IndexSearcher indexSearcher = new IndexSearcher(indexReader); - TermsAggregationBuilder aggregationBuilder = new TermsAggregationBuilder("_name", ValueType.STRING) + TermsAggregationBuilder aggregationBuilder = new TermsAggregationBuilder("_name").userValueTypeHint(ValueType.STRING) .field("string") .collectMode(Aggregator.SubAggCollectionMode.BREADTH_FIRST); MappedFieldType fieldType = new KeywordFieldMapper.KeywordFieldType(); @@ -184,7 +184,8 @@ public void testSimple() throws Exception { try (IndexReader indexReader = maybeWrapReaderEs(indexWriter.getReader())) { IndexSearcher indexSearcher = newIndexSearcher(indexReader); for (TermsAggregatorFactory.ExecutionMode executionMode : TermsAggregatorFactory.ExecutionMode.values()) { - TermsAggregationBuilder aggregationBuilder = new TermsAggregationBuilder("_name", ValueType.STRING) + TermsAggregationBuilder aggregationBuilder = new TermsAggregationBuilder("_name") + .userValueTypeHint(ValueType.STRING) .executionHint(executionMode.toString()) .field("string") .order(BucketOrder.key(true)); @@ -255,7 +256,8 @@ public void testStringIncludeExclude() throws Exception { fieldType.setHasDocValues(true); String executionHint = randomFrom(TermsAggregatorFactory.ExecutionMode.values()).toString(); - TermsAggregationBuilder aggregationBuilder = new TermsAggregationBuilder("_name", ValueType.STRING) + TermsAggregationBuilder aggregationBuilder = new TermsAggregationBuilder("_name") + .userValueTypeHint(ValueType.STRING) .executionHint(executionHint) .includeExclude(new IncludeExclude("val00.+", null)) .field("mv_field") @@ -293,7 +295,7 @@ public void testStringIncludeExclude() throws Exception { MappedFieldType fieldType2 = new KeywordFieldMapper.KeywordFieldType(); fieldType2.setName("sv_field"); fieldType2.setHasDocValues(true); - aggregationBuilder = new TermsAggregationBuilder("_name", ValueType.STRING) + aggregationBuilder = new TermsAggregationBuilder("_name").userValueTypeHint(ValueType.STRING) .executionHint(executionHint) .includeExclude(new IncludeExclude("val00.+", null)) .field("sv_field") @@ -317,7 +319,7 @@ public void testStringIncludeExclude() throws Exception { assertEquals(1L, result.getBuckets().get(4).getDocCount()); assertTrue(AggregationInspectionHelper.hasValue((InternalTerms)result)); - aggregationBuilder = new TermsAggregationBuilder("_name", ValueType.STRING) + aggregationBuilder = new TermsAggregationBuilder("_name").userValueTypeHint(ValueType.STRING) .executionHint(executionHint) .includeExclude(new IncludeExclude("val00.+", "(val000|val001)")) .field("mv_field") @@ -347,7 +349,7 @@ public void testStringIncludeExclude() throws Exception { assertEquals(1L, result.getBuckets().get(7).getDocCount()); assertTrue(AggregationInspectionHelper.hasValue((InternalTerms)result)); - aggregationBuilder = new TermsAggregationBuilder("_name", ValueType.STRING) + aggregationBuilder = new TermsAggregationBuilder("_name").userValueTypeHint(ValueType.STRING) .executionHint(executionHint) .includeExclude(new IncludeExclude(null, "val00.+")) .field("mv_field") @@ -364,7 +366,7 @@ public void testStringIncludeExclude() throws Exception { assertEquals(1L, result.getBuckets().get(1).getDocCount()); assertTrue(AggregationInspectionHelper.hasValue((InternalTerms)result)); - aggregationBuilder = new TermsAggregationBuilder("_name", ValueType.STRING) + aggregationBuilder = new TermsAggregationBuilder("_name").userValueTypeHint(ValueType.STRING) .executionHint(executionHint) .includeExclude(new IncludeExclude(new String[]{"val000", "val010"}, null)) .field("mv_field") @@ -381,7 +383,7 @@ public void testStringIncludeExclude() throws Exception { assertEquals(1L, result.getBuckets().get(1).getDocCount()); assertTrue(AggregationInspectionHelper.hasValue((InternalTerms)result)); - aggregationBuilder = new TermsAggregationBuilder("_name", ValueType.STRING) + aggregationBuilder = new TermsAggregationBuilder("_name").userValueTypeHint(ValueType.STRING) .executionHint(executionHint) .includeExclude(new IncludeExclude(null, new String[]{"val001", "val002", "val003", "val004", "val005", "val006", "val007", "val008", "val009", "val011"})) @@ -437,7 +439,8 @@ public void testNumericIncludeExclude() throws Exception { fieldType.setHasDocValues(true ); String executionHint = randomFrom(TermsAggregatorFactory.ExecutionMode.values()).toString(); - TermsAggregationBuilder aggregationBuilder = new TermsAggregationBuilder("_name", ValueType.LONG) + TermsAggregationBuilder aggregationBuilder = new TermsAggregationBuilder("_name") + .userValueTypeHint(ValueType.LONG) .executionHint(executionHint) .includeExclude(new IncludeExclude(new long[]{0, 5}, null)) .field("long_field") @@ -454,7 +457,7 @@ public void testNumericIncludeExclude() throws Exception { assertEquals(1L, result.getBuckets().get(1).getDocCount()); assertTrue(AggregationInspectionHelper.hasValue((InternalTerms)result)); - aggregationBuilder = new TermsAggregationBuilder("_name", ValueType.LONG) + aggregationBuilder = new TermsAggregationBuilder("_name").userValueTypeHint(ValueType.LONG) .executionHint(executionHint) .includeExclude(new IncludeExclude(null, new long[]{0, 5})) .field("long_field") @@ -478,7 +481,7 @@ public void testNumericIncludeExclude() throws Exception { fieldType = new NumberFieldMapper.NumberFieldType(NumberFieldMapper.NumberType.DOUBLE); fieldType.setName("double_field"); fieldType.setHasDocValues(true ); - aggregationBuilder = new TermsAggregationBuilder("_name", ValueType.DOUBLE) + aggregationBuilder = new TermsAggregationBuilder("_name").userValueTypeHint(ValueType.DOUBLE) .executionHint(executionHint) .includeExclude(new IncludeExclude(new double[]{0.0, 5.0}, null)) .field("double_field") @@ -495,7 +498,7 @@ public void testNumericIncludeExclude() throws Exception { assertEquals(1L, result.getBuckets().get(1).getDocCount()); assertTrue(AggregationInspectionHelper.hasValue((InternalTerms)result)); - aggregationBuilder = new TermsAggregationBuilder("_name", ValueType.DOUBLE) + aggregationBuilder = new TermsAggregationBuilder("_name").userValueTypeHint(ValueType.DOUBLE) .executionHint(executionHint) .includeExclude(new IncludeExclude(null, new double[]{0.0, 5.0})) .field("double_field") @@ -656,7 +659,8 @@ private void termsAggregator(ValueType valueType, MappedFieldType fieldType, String executionHint = randomFrom(TermsAggregatorFactory.ExecutionMode.values()).toString(); logger.info("bucket_order={} size={} execution_hint={}", bucketOrder, size, executionHint); IndexSearcher indexSearcher = newIndexSearcher(indexReader); - AggregationBuilder aggregationBuilder = new TermsAggregationBuilder("_name", valueType) + AggregationBuilder aggregationBuilder = new TermsAggregationBuilder("_name") + .userValueTypeHint(valueType) .executionHint(executionHint) .size(size) .shardSize(size) @@ -684,7 +688,8 @@ private void termsAggregator(ValueType valueType, MappedFieldType fieldType, if (multiValued == false) { aggregationBuilder = new FilterAggregationBuilder("_name1", QueryBuilders.termQuery("include", "yes")); - aggregationBuilder.subAggregation(new TermsAggregationBuilder("_name2", valueType) + aggregationBuilder.subAggregation(new TermsAggregationBuilder("_name2") + .userValueTypeHint(valueType) .executionHint(executionHint) .size(numTerms) .collectMode(randomFrom(Aggregator.SubAggCollectionMode.values())) @@ -750,7 +755,8 @@ private void termsAggregatorWithNestedMaxAgg(ValueType valueType, MappedFiel logger.info("bucket_order={} size={} execution_hint={}, collect_mode={}", bucketOrder, size, executionHint, collectionMode); IndexSearcher indexSearcher = newIndexSearcher(indexReader); - AggregationBuilder aggregationBuilder = new TermsAggregationBuilder("_name", valueType) + AggregationBuilder aggregationBuilder = new TermsAggregationBuilder("_name") + .userValueTypeHint(valueType) .executionHint(executionHint) .collectMode(collectionMode) .size(size) @@ -796,7 +802,8 @@ public void testEmpty() throws Exception { fieldType1.setHasDocValues(true); try (IndexReader indexReader = maybeWrapReaderEs(indexWriter.getReader())) { IndexSearcher indexSearcher = newIndexSearcher(indexReader); - TermsAggregationBuilder aggregationBuilder = new TermsAggregationBuilder("_name", ValueType.STRING) + TermsAggregationBuilder aggregationBuilder = new TermsAggregationBuilder("_name") + .userValueTypeHint(ValueType.STRING) .field("string"); Aggregator aggregator = createAggregator(aggregationBuilder, indexSearcher, fieldType1); aggregator.preCollection(); @@ -806,7 +813,7 @@ public void testEmpty() throws Exception { assertEquals("_name", result.getName()); assertEquals(0, result.getBuckets().size()); - aggregationBuilder = new TermsAggregationBuilder("_name", ValueType.LONG) + aggregationBuilder = new TermsAggregationBuilder("_name").userValueTypeHint(ValueType.LONG) .field("long"); aggregator = createAggregator(aggregationBuilder, indexSearcher, fieldType2); aggregator.preCollection(); @@ -816,7 +823,7 @@ public void testEmpty() throws Exception { assertEquals("_name", result.getName()); assertEquals(0, result.getBuckets().size()); - aggregationBuilder = new TermsAggregationBuilder("_name", ValueType.DOUBLE) + aggregationBuilder = new TermsAggregationBuilder("_name").userValueTypeHint(ValueType.DOUBLE) .field("double"); aggregator = createAggregator(aggregationBuilder, indexSearcher, fieldType3); aggregator.preCollection(); @@ -838,7 +845,8 @@ public void testUnmapped() throws Exception { ValueType[] valueTypes = new ValueType[]{ValueType.STRING, ValueType.LONG, ValueType.DOUBLE}; String[] fieldNames = new String[]{"string", "long", "double"}; for (int i = 0; i < fieldNames.length; i++) { - TermsAggregationBuilder aggregationBuilder = new TermsAggregationBuilder("_name", valueTypes[i]) + TermsAggregationBuilder aggregationBuilder = new TermsAggregationBuilder("_name") + .userValueTypeHint(valueTypes[i]) .field(fieldNames[i]); Aggregator aggregator = createAggregator(aggregationBuilder, indexSearcher, (MappedFieldType) null); aggregator.preCollection(); @@ -875,7 +883,8 @@ public void testUnmappedWithMissing() throws Exception { for (int i = 0; i < fieldNames.length; i++) { - TermsAggregationBuilder aggregationBuilder = new TermsAggregationBuilder("_name", valueTypes[i]) + TermsAggregationBuilder aggregationBuilder = new TermsAggregationBuilder("_name") + .userValueTypeHint(valueTypes[i]) .field(fieldNames[i]).missing(missingValues[i]); Aggregator aggregator = createAggregator(aggregationBuilder, indexSearcher, fieldType1); aggregator.preCollection(); @@ -910,7 +919,7 @@ public void testRangeField() throws Exception { fieldType.setName(fieldName); IndexSearcher indexSearcher = newIndexSearcher(indexReader); - TermsAggregationBuilder aggregationBuilder = new TermsAggregationBuilder("_name", null) .field(fieldName); + TermsAggregationBuilder aggregationBuilder = new TermsAggregationBuilder("_name") .field(fieldName); // Note - other places we throw IllegalArgumentException expectThrows(AggregationExecutionException.class, () -> { createAggregator(aggregationBuilder, indexSearcher, fieldType); @@ -934,7 +943,7 @@ public void testGeoPointField() throws Exception { fieldType.setName("field"); IndexSearcher indexSearcher = newIndexSearcher(indexReader); - TermsAggregationBuilder aggregationBuilder = new TermsAggregationBuilder("_name", null) .field(field); + TermsAggregationBuilder aggregationBuilder = new TermsAggregationBuilder("_name") .field(field); // Note - other places we throw IllegalArgumentException expectThrows(AggregationExecutionException.class, () -> { createAggregator(aggregationBuilder, indexSearcher, fieldType); @@ -958,7 +967,7 @@ public void testIpField() throws Exception { fieldType.setName("field"); IndexSearcher indexSearcher = newIndexSearcher(indexReader); - TermsAggregationBuilder aggregationBuilder = new TermsAggregationBuilder("_name", null) .field(field); + TermsAggregationBuilder aggregationBuilder = new TermsAggregationBuilder("_name") .field(field); // Note - other places we throw IllegalArgumentException Aggregator aggregator = createAggregator(aggregationBuilder, indexSearcher, fieldType); aggregator.preCollection(); @@ -993,12 +1002,13 @@ public void testNestedTermsAgg() throws Exception { IndexSearcher indexSearcher = newIndexSearcher(indexReader); String executionHint = randomFrom(TermsAggregatorFactory.ExecutionMode.values()).toString(); Aggregator.SubAggCollectionMode collectionMode = randomFrom(Aggregator.SubAggCollectionMode.values()); - TermsAggregationBuilder aggregationBuilder = new TermsAggregationBuilder("_name1", ValueType.STRING) + TermsAggregationBuilder aggregationBuilder = new TermsAggregationBuilder("_name1") + .userValueTypeHint(ValueType.STRING) .executionHint(executionHint) .collectMode(collectionMode) .field("field1") .order(BucketOrder.key(true)) - .subAggregation(new TermsAggregationBuilder("_name2", ValueType.STRING) + .subAggregation(new TermsAggregationBuilder("_name2").userValueTypeHint(ValueType.STRING) .executionHint(executionHint) .collectMode(collectionMode) .field("field2") @@ -1036,7 +1046,7 @@ public void testNestedTermsAgg() throws Exception { public void testMixLongAndDouble() throws Exception { for (TermsAggregatorFactory.ExecutionMode executionMode : TermsAggregatorFactory.ExecutionMode.values()) { - TermsAggregationBuilder aggregationBuilder = new TermsAggregationBuilder("_name", ValueType.LONG) + TermsAggregationBuilder aggregationBuilder = new TermsAggregationBuilder("_name").userValueTypeHint(ValueType.LONG) .executionHint(executionMode.toString()) .field("number") .order(BucketOrder.key(true)); @@ -1108,13 +1118,13 @@ public void testGlobalAggregationWithScore() throws IOException { Aggregator.SubAggCollectionMode collectionMode = randomFrom(Aggregator.SubAggCollectionMode.values()); GlobalAggregationBuilder globalBuilder = new GlobalAggregationBuilder("global") .subAggregation( - new TermsAggregationBuilder("terms", ValueType.STRING) + new TermsAggregationBuilder("terms").userValueTypeHint(ValueType.STRING) .executionHint(executionHint) .collectMode(collectionMode) .field("keyword") .order(BucketOrder.key(true)) .subAggregation( - new TermsAggregationBuilder("sub_terms", ValueType.STRING) + new TermsAggregationBuilder("sub_terms").userValueTypeHint(ValueType.STRING) .executionHint(executionHint) .collectMode(collectionMode) .field("keyword").order(BucketOrder.key(true)) @@ -1161,7 +1171,7 @@ public void testWithNestedAggregations() throws IOException { for (Aggregator.SubAggCollectionMode mode : Aggregator.SubAggCollectionMode.values()) { for (boolean withScore : new boolean[]{true, false}) { NestedAggregationBuilder nested = new NestedAggregationBuilder("nested", "nested_object") - .subAggregation(new TermsAggregationBuilder("terms", ValueType.LONG) + .subAggregation(new TermsAggregationBuilder("terms").userValueTypeHint(ValueType.LONG) .field("nested_value") // force the breadth_first mode .collectMode(mode) @@ -1227,7 +1237,7 @@ public void testOrderByPipelineAggregation() throws Exception { "script", new Script("2.718")); TermsAggregationBuilder termsAgg = terms("terms") .field("field") - .valueType(ValueType.STRING) + .userValueTypeHint(ValueType.STRING) .order(BucketOrder.aggregation("script", true)) .subAggregation(bucketScriptAgg); diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/metrics/AvgAggregatorTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/metrics/AvgAggregatorTests.java index 46f08d786a856..c832e890179f5 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/metrics/AvgAggregatorTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/metrics/AvgAggregatorTests.java @@ -522,7 +522,7 @@ public void testOrderByEmptyAggregation() throws IOException { fieldType.setName("value"); fieldType.setHasDocValues(true); - AggregationBuilder aggregationBuilder = new TermsAggregationBuilder("terms", ValueType.NUMERIC) + AggregationBuilder aggregationBuilder = new TermsAggregationBuilder("terms").userValueTypeHint(ValueType.NUMERIC) .field("value") .order(BucketOrder.compound(BucketOrder.aggregation("filter>avg", true))) .subAggregation(AggregationBuilders.filter("filter", termQuery("value", 100)) diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/metrics/CardinalityAggregatorTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/metrics/CardinalityAggregatorTests.java index 53a01d08bdcf2..48315fec2c51f 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/metrics/CardinalityAggregatorTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/metrics/CardinalityAggregatorTests.java @@ -64,7 +64,7 @@ public void testRangeFieldValues() throws IOException { final String fieldName = "rangeField"; MappedFieldType fieldType = new RangeFieldMapper.Builder(fieldName, rangeType).fieldType(); fieldType.setName(fieldName); - final CardinalityAggregationBuilder aggregationBuilder = new CardinalityAggregationBuilder("_name", null).field(fieldName); + final CardinalityAggregationBuilder aggregationBuilder = new CardinalityAggregationBuilder("_name").field(fieldName); testCase(aggregationBuilder, new MatchAllDocsQuery(), iw -> { iw.addDocument(singleton(new BinaryDocValuesField(fieldName, rangeType.encodeRanges(singleton(range1))))); iw.addDocument(singleton(new BinaryDocValuesField(fieldName, rangeType.encodeRanges(singleton(range1))))); @@ -131,7 +131,7 @@ public void testQueryFiltersAll() throws IOException { } public void testUnmappedMissingString() throws IOException { - CardinalityAggregationBuilder aggregationBuilder = new CardinalityAggregationBuilder("name", null) + CardinalityAggregationBuilder aggregationBuilder = new CardinalityAggregationBuilder("name") .field("number").missing("🍌🍌🍌"); testCase(aggregationBuilder, new MatchAllDocsQuery(), iw -> { @@ -145,7 +145,7 @@ public void testUnmappedMissingString() throws IOException { } public void testUnmappedMissingNumber() throws IOException { - CardinalityAggregationBuilder aggregationBuilder = new CardinalityAggregationBuilder("name", null) + CardinalityAggregationBuilder aggregationBuilder = new CardinalityAggregationBuilder("name") .field("number").missing(1234); testCase(aggregationBuilder, new MatchAllDocsQuery(), iw -> { @@ -159,7 +159,7 @@ public void testUnmappedMissingNumber() throws IOException { } public void testUnmappedMissingGeoPoint() throws IOException { - CardinalityAggregationBuilder aggregationBuilder = new CardinalityAggregationBuilder("name", null) + CardinalityAggregationBuilder aggregationBuilder = new CardinalityAggregationBuilder("name") .field("number").missing(new GeoPoint(42.39561, -71.13051)); testCase(aggregationBuilder, new MatchAllDocsQuery(), iw -> { @@ -177,7 +177,7 @@ private void testCase(Query query, CheckedConsumer { @Override protected final CardinalityAggregationBuilder createTestAggregatorBuilder() { - CardinalityAggregationBuilder factory = new CardinalityAggregationBuilder(randomAlphaOfLengthBetween(3, 10), null); + CardinalityAggregationBuilder factory = new CardinalityAggregationBuilder(randomAlphaOfLengthBetween(3, 10)); String field = randomNumericField(); randomFieldOrScript(factory, field); if (randomBoolean()) { diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/metrics/ExtendedStatsAggregatorTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/metrics/ExtendedStatsAggregatorTests.java index 83713ff52af84..001f18e8eea47 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/metrics/ExtendedStatsAggregatorTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/metrics/ExtendedStatsAggregatorTests.java @@ -42,6 +42,8 @@ public class ExtendedStatsAggregatorTests extends AggregatorTestCase { private static final double TOLERANCE = 1e-5; + // TODO: Add script test cases. Should fail with defaultValuesSourceType() commented out. + public void testEmpty() throws IOException { MappedFieldType ft = new NumberFieldMapper.NumberFieldType(NumberFieldMapper.NumberType.LONG); diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/metrics/HDRPercentilesAggregatorTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/metrics/HDRPercentilesAggregatorTests.java index f08a89657c63b..11ffc3ee9953b 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/metrics/HDRPercentilesAggregatorTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/metrics/HDRPercentilesAggregatorTests.java @@ -19,9 +19,11 @@ package org.elasticsearch.search.aggregations.metrics; +import org.apache.lucene.document.BinaryDocValuesField; import org.apache.lucene.document.LongPoint; import org.apache.lucene.document.NumericDocValuesField; import org.apache.lucene.document.SortedNumericDocValuesField; +import org.apache.lucene.document.SortedSetDocValuesField; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.RandomIndexWriter; @@ -30,17 +32,18 @@ import org.apache.lucene.search.MatchAllDocsQuery; import org.apache.lucene.search.Query; import org.apache.lucene.store.Directory; +import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.CheckedConsumer; +import org.elasticsearch.index.mapper.KeywordFieldMapper; import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.NumberFieldMapper; +import org.elasticsearch.index.mapper.RangeFieldMapper; +import org.elasticsearch.index.mapper.RangeType; import org.elasticsearch.search.aggregations.AggregatorTestCase; -import org.elasticsearch.search.aggregations.metrics.HDRPercentilesAggregator; -import org.elasticsearch.search.aggregations.metrics.InternalHDRPercentiles; -import org.elasticsearch.search.aggregations.metrics.PercentilesAggregationBuilder; -import org.elasticsearch.search.aggregations.metrics.PercentilesMethod; import org.elasticsearch.search.aggregations.support.AggregationInspectionHelper; import java.io.IOException; +import java.util.Collections; import java.util.function.Consumer; import static java.util.Arrays.asList; @@ -57,6 +60,39 @@ public void testNoDocs() throws IOException { }); } + /** + * Attempting to use HDRPercentileAggregation on a string field throws IllegalArgumentException + */ + public void testStringField() throws IOException { + final String fieldName = "string"; + MappedFieldType fieldType = new KeywordFieldMapper.KeywordFieldType(); + fieldType.setName(fieldName); + fieldType.setHasDocValues(true); + expectThrows(IllegalArgumentException.class, + () -> testCase(new DocValuesFieldExistsQuery(fieldName), iw -> { + iw.addDocument(singleton(new SortedSetDocValuesField("string", new BytesRef("bogus")))); + iw.addDocument(singleton(new SortedSetDocValuesField("string", new BytesRef("zwomp")))); + iw.addDocument(singleton(new SortedSetDocValuesField("string", new BytesRef("foobar")))); + }, hdr -> {}, fieldType, fieldName)); + } + + /** + * Attempting to use HDRPercentileAggregation on a range field throws IllegalArgumentException + */ + @AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/42949") + public void testRangeField() throws IOException { + // Currently fails (throws ClassCast exception), but should be fixed once HDRPercentileAggregation uses the ValuesSource registry + final String fieldName = "range"; + MappedFieldType fieldType = new RangeFieldMapper.Builder(fieldName, RangeType.DOUBLE).fieldType(); + fieldType.setName(fieldName); + RangeFieldMapper.Range range =new RangeFieldMapper.Range(RangeType.DOUBLE, 1.0D, 5.0D, true, true); + BytesRef encodedRange = RangeType.DOUBLE.encodeRanges(Collections.singleton(range)); + expectThrows(IllegalArgumentException.class, + () -> testCase(new DocValuesFieldExistsQuery(fieldName), iw -> { + iw.addDocument(singleton(new BinaryDocValuesField(fieldName, encodedRange))); + }, hdr -> {}, fieldType, fieldName)); + } + public void testNoMatchingField() throws IOException { testCase(new MatchAllDocsQuery(), iw -> { iw.addDocument(singleton(new SortedNumericDocValuesField("wrong_number", 7))); @@ -123,6 +159,13 @@ public void testQueryFiltering() throws IOException { private void testCase(Query query, CheckedConsumer buildIndex, Consumer verify) throws IOException { + MappedFieldType fieldType = new NumberFieldMapper.NumberFieldType(NumberFieldMapper.NumberType.LONG); + fieldType.setName("number"); + testCase(query, buildIndex, verify, fieldType, "number"); + } + + private void testCase(Query query, CheckedConsumer buildIndex, + Consumer verify, MappedFieldType fieldType, String fieldName) throws IOException { try (Directory directory = newDirectory()) { try (RandomIndexWriter indexWriter = new RandomIndexWriter(random(), directory)) { buildIndex.accept(indexWriter); @@ -132,10 +175,8 @@ private void testCase(Query query, CheckedConsumermax", true))) .subAggregation(AggregationBuilders.filter("filter", termQuery("value", 100)) @@ -817,7 +817,7 @@ public void testEarlyTermination() throws Exception { IndexSearcher indexSearcher = newSearcher(indexReader, true, true); MaxAggregationBuilder maxAggregationBuilder = new MaxAggregationBuilder("max") .field("values"); - ValueCountAggregationBuilder countAggregationBuilder = new ValueCountAggregationBuilder("count", null) + ValueCountAggregationBuilder countAggregationBuilder = new ValueCountAggregationBuilder("count") .field("values"); MaxAggregator maxAggregator = createAggregator(maxAggregationBuilder, indexSearcher, fieldType); @@ -867,9 +867,10 @@ public void testNestedEarlyTermination() throws Exception { for (Aggregator.SubAggCollectionMode collectionMode : Aggregator.SubAggCollectionMode.values()) { MaxAggregationBuilder maxAggregationBuilder = new MaxAggregationBuilder("max") .field("values"); - ValueCountAggregationBuilder countAggregationBuilder = new ValueCountAggregationBuilder("count", null) + ValueCountAggregationBuilder countAggregationBuilder = new ValueCountAggregationBuilder("count") .field("values"); - TermsAggregationBuilder termsAggregationBuilder = new TermsAggregationBuilder("terms", ValueType.NUMERIC) + TermsAggregationBuilder termsAggregationBuilder = new TermsAggregationBuilder("terms") + .userValueTypeHint(ValueType.NUMERIC) .field("value").collectMode(collectionMode) .subAggregation(new MaxAggregationBuilder("sub_max").field("invalid")); diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/metrics/MinAggregatorTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/metrics/MinAggregatorTests.java index 4a9cfdd31fd34..24b9874453cd0 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/metrics/MinAggregatorTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/metrics/MinAggregatorTests.java @@ -80,7 +80,6 @@ import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import org.elasticsearch.search.aggregations.support.AggregationInspectionHelper; import org.elasticsearch.search.aggregations.support.FieldContext; -import org.elasticsearch.search.aggregations.support.ValueType; import org.elasticsearch.search.aggregations.support.ValuesSourceConfig; import org.elasticsearch.search.internal.SearchContext; import org.elasticsearch.search.lookup.LeafDocLookup; @@ -594,7 +593,7 @@ public void testMultiValuedFieldWithScriptParams() throws IOException { } public void testOrderByEmptyAggregation() throws IOException { - AggregationBuilder termsBuilder = new TermsAggregationBuilder("terms", ValueType.NUMERIC) + AggregationBuilder termsBuilder = new TermsAggregationBuilder("terms") .field("number") .order(BucketOrder.compound(BucketOrder.aggregation("filter>min", true))) .subAggregation(new FilterAggregationBuilder("filter", termQuery("number", 100)) @@ -660,11 +659,11 @@ public void testScriptCaching() throws IOException { fieldType.setName("number"); MinAggregationBuilder aggregationBuilder = new MinAggregationBuilder("min") .field("number") - .script(new Script(ScriptType.INLINE, MockScriptEngine.NAME, INVERT_SCRIPT, Collections.emptyMap()));; + .script(new Script(ScriptType.INLINE, MockScriptEngine.NAME, INVERT_SCRIPT, Collections.emptyMap())); MinAggregationBuilder nonDeterministicAggregationBuilder = new MinAggregationBuilder("min") .field("number") - .script(new Script(ScriptType.INLINE, MockScriptEngine.NAME, RANDOM_SCRIPT, Collections.emptyMap()));; + .script(new Script(ScriptType.INLINE, MockScriptEngine.NAME, RANDOM_SCRIPT, Collections.emptyMap())); try (Directory directory = newDirectory()) { RandomIndexWriter indexWriter = new RandomIndexWriter(random(), directory); diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/metrics/StatsAggregatorTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/metrics/StatsAggregatorTests.java index 28b1514545506..0f16dd107f96b 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/metrics/StatsAggregatorTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/metrics/StatsAggregatorTests.java @@ -41,6 +41,8 @@ public class StatsAggregatorTests extends AggregatorTestCase { static final double TOLERANCE = 1e-10; + // TODO: Script tests, should fail with defaultValuesSourceType disabled. + public void testEmpty() throws IOException { MappedFieldType ft = new NumberFieldMapper.NumberFieldType(NumberFieldMapper.NumberType.LONG); diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/metrics/ValueCountAggregatorTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/metrics/ValueCountAggregatorTests.java index e3060d4c78ef0..83dc208a59c85 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/metrics/ValueCountAggregatorTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/metrics/ValueCountAggregatorTests.java @@ -125,7 +125,7 @@ public void testQueryFiltersAll() throws IOException { } public void testUnmappedMissingString() throws IOException { - ValueCountAggregationBuilder aggregationBuilder = new ValueCountAggregationBuilder("name", null) + ValueCountAggregationBuilder aggregationBuilder = new ValueCountAggregationBuilder("name") .field("number").missing("🍌🍌🍌"); testCase(aggregationBuilder, new MatchAllDocsQuery(), iw -> { @@ -139,7 +139,7 @@ public void testUnmappedMissingString() throws IOException { } public void testUnmappedMissingNumber() throws IOException { - ValueCountAggregationBuilder aggregationBuilder = new ValueCountAggregationBuilder("name", null) + ValueCountAggregationBuilder aggregationBuilder = new ValueCountAggregationBuilder("name") .field("number").missing(1234); testCase(aggregationBuilder, new MatchAllDocsQuery(), iw -> { @@ -153,7 +153,7 @@ public void testUnmappedMissingNumber() throws IOException { } public void testUnmappedMissingGeoPoint() throws IOException { - ValueCountAggregationBuilder aggregationBuilder = new ValueCountAggregationBuilder("name", null) + ValueCountAggregationBuilder aggregationBuilder = new ValueCountAggregationBuilder("name") .field("number").missing(new GeoPoint(42.39561, -71.13051)); testCase(aggregationBuilder, new MatchAllDocsQuery(), iw -> { @@ -173,7 +173,7 @@ public void testRangeFieldValues() throws IOException { final String fieldName = "rangeField"; MappedFieldType fieldType = new RangeFieldMapper.Builder(fieldName, rangeType).fieldType(); fieldType.setName(fieldName); - final ValueCountAggregationBuilder aggregationBuilder = new ValueCountAggregationBuilder("_name", null).field(fieldName); + final ValueCountAggregationBuilder aggregationBuilder = new ValueCountAggregationBuilder("_name").field(fieldName); testCase(aggregationBuilder, new MatchAllDocsQuery(), iw -> { iw.addDocument(singleton(new BinaryDocValuesField(fieldName, rangeType.encodeRanges(singleton(range1))))); iw.addDocument(singleton(new BinaryDocValuesField(fieldName, rangeType.encodeRanges(singleton(range1))))); @@ -189,11 +189,23 @@ private void testCase(Query query, ValueType valueType, CheckedConsumer indexer, Consumer verify) throws IOException { + // Test both with and without the userValueTypeHint + testCase(query, valueType, indexer, verify, true); + testCase(query, valueType, indexer, verify, false); + } + + private void testCase(Query query, + ValueType valueType, + CheckedConsumer indexer, + Consumer verify, boolean testWithHint) throws IOException { MappedFieldType fieldType = createMappedFieldType(valueType); fieldType.setName(FIELD_NAME); fieldType.setHasDocValues(true); - ValueCountAggregationBuilder aggregationBuilder = new ValueCountAggregationBuilder("_name", valueType); + ValueCountAggregationBuilder aggregationBuilder = new ValueCountAggregationBuilder("_name"); + if (valueType != null && testWithHint) { + aggregationBuilder.userValueTypeHint(valueType); + } aggregationBuilder.field(FIELD_NAME); testCase(aggregationBuilder, query, indexer, verify, fieldType); diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/metrics/ValueCountTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/metrics/ValueCountTests.java index 591c096eea147..846bf79afc8d2 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/metrics/ValueCountTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/metrics/ValueCountTests.java @@ -25,7 +25,7 @@ public class ValueCountTests extends BaseAggregationTestCase aggBuilders = new HashSet<>(); aggBuilders.add(singleBucketAgg); aggBuilders.add(multiBucketAgg); diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/BucketScriptAggregatorTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/BucketScriptAggregatorTests.java index 97e5fac24dcda..8f2eaa83509ce 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/BucketScriptAggregatorTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/BucketScriptAggregatorTests.java @@ -78,7 +78,7 @@ public void testScript() throws IOException { fieldType1.setHasDocValues(true); FiltersAggregationBuilder filters = new FiltersAggregationBuilder("placeholder", new MatchAllQueryBuilder()) - .subAggregation(new TermsAggregationBuilder("the_terms", ValueType.STRING).field("the_field") + .subAggregation(new TermsAggregationBuilder("the_terms").userValueTypeHint(ValueType.STRING).field("the_field") .subAggregation(new AvgAggregationBuilder("the_avg").field("number_field"))) .subAggregation(new BucketScriptPipelineAggregationBuilder("bucket_script", Collections.singletonMap("the_avg", "the_terms['test1']>the_avg.value"), diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/ExtendedStatsBucketTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/ExtendedStatsBucketTests.java index 9930541cb007e..cc7d9df6541ab 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/ExtendedStatsBucketTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/ExtendedStatsBucketTests.java @@ -62,7 +62,7 @@ public void testSigmaFromInt() throws Exception { public void testValidate() { AggregationBuilder singleBucketAgg = new GlobalAggregationBuilder("global"); - AggregationBuilder multiBucketAgg = new TermsAggregationBuilder("terms", ValueType.STRING); + AggregationBuilder multiBucketAgg = new TermsAggregationBuilder("terms").userValueTypeHint(ValueType.STRING); final Set aggBuilders = new HashSet<>(); aggBuilders.add(singleBucketAgg); aggBuilders.add(multiBucketAgg); diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/MaxBucketTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/MaxBucketTests.java index c55152c68c3a6..e370ac5084877 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/MaxBucketTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/MaxBucketTests.java @@ -37,7 +37,7 @@ protected MaxBucketPipelineAggregationBuilder doCreateTestAggregatorFactory(Stri public void testValidate() { AggregationBuilder singleBucketAgg = new GlobalAggregationBuilder("global"); - AggregationBuilder multiBucketAgg = new TermsAggregationBuilder("terms", ValueType.STRING); + AggregationBuilder multiBucketAgg = new TermsAggregationBuilder("terms").userValueTypeHint(ValueType.STRING); final Set aggBuilders = new HashSet<>(); aggBuilders.add(singleBucketAgg); aggBuilders.add(multiBucketAgg); diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/MinBucketTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/MinBucketTests.java index 317f1360c7845..8c63876d6d208 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/MinBucketTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/MinBucketTests.java @@ -37,7 +37,7 @@ protected MinBucketPipelineAggregationBuilder doCreateTestAggregatorFactory(Stri public void testValidate() { AggregationBuilder singleBucketAgg = new GlobalAggregationBuilder("global"); - AggregationBuilder multiBucketAgg = new TermsAggregationBuilder("terms", ValueType.STRING); + AggregationBuilder multiBucketAgg = new TermsAggregationBuilder("terms").userValueTypeHint(ValueType.STRING); final Set aggBuilders = new HashSet<>(); aggBuilders.add(singleBucketAgg); aggBuilders.add(multiBucketAgg); diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/PercentilesBucketTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/PercentilesBucketTests.java index 165312a5bdef5..817e79cf5c9a7 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/PercentilesBucketTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/PercentilesBucketTests.java @@ -66,7 +66,7 @@ public void testPercentsFromMixedArray() throws Exception { public void testValidate() { AggregationBuilder singleBucketAgg = new GlobalAggregationBuilder("global"); - AggregationBuilder multiBucketAgg = new TermsAggregationBuilder("terms", ValueType.STRING); + AggregationBuilder multiBucketAgg = new TermsAggregationBuilder("terms").userValueTypeHint(ValueType.STRING); final Set aggBuilders = new HashSet<>(); aggBuilders.add(singleBucketAgg); aggBuilders.add(multiBucketAgg); diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/StatsBucketTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/StatsBucketTests.java index bf2ef7615df66..048682a502e5c 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/StatsBucketTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/StatsBucketTests.java @@ -38,7 +38,7 @@ protected StatsBucketPipelineAggregationBuilder doCreateTestAggregatorFactory(St public void testValidate() { AggregationBuilder singleBucketAgg = new GlobalAggregationBuilder("global"); - AggregationBuilder multiBucketAgg = new TermsAggregationBuilder("terms", ValueType.STRING); + AggregationBuilder multiBucketAgg = new TermsAggregationBuilder("terms").userValueTypeHint(ValueType.STRING); final Set aggBuilders = new HashSet<>(); aggBuilders.add(singleBucketAgg); aggBuilders.add(multiBucketAgg); diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/SumBucketTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/SumBucketTests.java index fdba878524146..06db40237af25 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/SumBucketTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/pipeline/SumBucketTests.java @@ -37,7 +37,7 @@ protected SumBucketPipelineAggregationBuilder doCreateTestAggregatorFactory(Stri public void testValidate() { AggregationBuilder singleBucketAgg = new GlobalAggregationBuilder("global"); - AggregationBuilder multiBucketAgg = new TermsAggregationBuilder("terms", ValueType.STRING); + AggregationBuilder multiBucketAgg = new TermsAggregationBuilder("terms").userValueTypeHint(ValueType.STRING); final Set aggBuilders = new HashSet<>(); aggBuilders.add(singleBucketAgg); aggBuilders.add(multiBucketAgg); diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/support/ValueTypeTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/support/ValueTypeTests.java index 84995277fb7da..55ae7deb52a04 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/support/ValueTypeTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/support/ValueTypeTests.java @@ -35,15 +35,48 @@ public void testResolve() { assertEquals(ValueType.IP, ValueType.resolveForScript("ip")); assertEquals(ValueType.BOOLEAN, ValueType.resolveForScript("boolean")); } - + public void testCompatibility() { assertTrue(ValueType.DOUBLE.isA(ValueType.NUMERIC)); + assertTrue(ValueType.DOUBLE.isA(ValueType.NUMBER)); + assertTrue(ValueType.DOUBLE.isA(ValueType.LONG)); + assertTrue(ValueType.DOUBLE.isA(ValueType.BOOLEAN)); + assertTrue(ValueType.DOUBLE.isA(ValueType.DATE)); + assertTrue(ValueType.DOUBLE.isA(ValueType.DOUBLE)); + + assertTrue(ValueType.LONG.isA(ValueType.NUMERIC)); + assertTrue(ValueType.LONG.isA(ValueType.NUMBER)); + assertTrue(ValueType.LONG.isA(ValueType.LONG)); + assertTrue(ValueType.LONG.isA(ValueType.BOOLEAN)); + assertTrue(ValueType.LONG.isA(ValueType.DATE)); + assertTrue(ValueType.LONG.isA(ValueType.DOUBLE)); + + assertTrue(ValueType.DATE.isA(ValueType.NUMERIC)); + assertTrue(ValueType.DATE.isA(ValueType.NUMBER)); assertTrue(ValueType.DATE.isA(ValueType.LONG)); + assertTrue(ValueType.DATE.isA(ValueType.BOOLEAN)); + assertTrue(ValueType.DATE.isA(ValueType.DATE)); + assertTrue(ValueType.DATE.isA(ValueType.DOUBLE)); + + assertTrue(ValueType.NUMERIC.isA(ValueType.NUMERIC)); assertTrue(ValueType.NUMERIC.isA(ValueType.NUMBER)); + assertTrue(ValueType.NUMERIC.isA(ValueType.LONG)); + assertTrue(ValueType.NUMERIC.isA(ValueType.BOOLEAN)); + assertTrue(ValueType.NUMERIC.isA(ValueType.DATE)); + assertTrue(ValueType.NUMERIC.isA(ValueType.DOUBLE)); + + assertTrue(ValueType.BOOLEAN.isA(ValueType.NUMERIC)); assertTrue(ValueType.BOOLEAN.isA(ValueType.NUMBER)); + assertTrue(ValueType.BOOLEAN.isA(ValueType.LONG)); + assertTrue(ValueType.BOOLEAN.isA(ValueType.BOOLEAN)); + assertTrue(ValueType.BOOLEAN.isA(ValueType.DATE)); + assertTrue(ValueType.BOOLEAN.isA(ValueType.DOUBLE)); + assertFalse(ValueType.STRING.isA(ValueType.NUMBER)); assertFalse(ValueType.DATE.isA(ValueType.IP)); - } + assertTrue(ValueType.IP.isA(ValueType.STRING)); + assertTrue(ValueType.STRING.isA(ValueType.IP)); + } } 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 913aaf13264b3..2dbe8ddcec569 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 @@ -15,8 +15,6 @@ import org.elasticsearch.search.aggregations.AggregationBuilder; import org.elasticsearch.search.aggregations.AggregatorFactories; import org.elasticsearch.search.aggregations.AggregatorFactory; -import org.elasticsearch.search.aggregations.support.CoreValuesSourceType; -import org.elasticsearch.search.aggregations.support.ValueType; import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder; import org.elasticsearch.search.aggregations.support.ValuesSourceConfig; import org.elasticsearch.search.aggregations.support.ValuesSourceParserHelper; @@ -45,7 +43,7 @@ public static StringStatsAggregationBuilder parse(String aggregationName, XConte } public StringStatsAggregationBuilder(String name) { - super(name, ValueType.STRING); + super(name); } public StringStatsAggregationBuilder(StringStatsAggregationBuilder clone, @@ -57,7 +55,7 @@ public StringStatsAggregationBuilder(StringStatsAggregationBuilder clone, /** Read from a stream. */ public StringStatsAggregationBuilder(StreamInput in) throws IOException { - super(in, CoreValuesSourceType.BYTES, ValueType.STRING); + super(in); this.showDistribution = in.readBoolean(); } diff --git a/x-pack/plugin/analytics/src/test/java/org/elasticsearch/xpack/analytics/cumulativecardinality/CumulativeCardinalityAggregatorTests.java b/x-pack/plugin/analytics/src/test/java/org/elasticsearch/xpack/analytics/cumulativecardinality/CumulativeCardinalityAggregatorTests.java index 795bdb907786c..e4c24c2971753 100644 --- a/x-pack/plugin/analytics/src/test/java/org/elasticsearch/xpack/analytics/cumulativecardinality/CumulativeCardinalityAggregatorTests.java +++ b/x-pack/plugin/analytics/src/test/java/org/elasticsearch/xpack/analytics/cumulativecardinality/CumulativeCardinalityAggregatorTests.java @@ -82,7 +82,8 @@ public void testSimple() throws IOException { DateHistogramAggregationBuilder aggBuilder = new DateHistogramAggregationBuilder("histo"); aggBuilder.calendarInterval(DateHistogramInterval.DAY).field(HISTO_FIELD); - aggBuilder.subAggregation(new CardinalityAggregationBuilder("the_cardinality", ValueType.NUMERIC).field(VALUE_FIELD)); + aggBuilder.subAggregation(new CardinalityAggregationBuilder("the_cardinality").userValueTypeHint(ValueType.NUMERIC) + .field(VALUE_FIELD)); aggBuilder.subAggregation(new CumulativeCardinalityPipelineAggregationBuilder("cumulative_card", "the_cardinality")); executeTestCase(query, aggBuilder, histogram -> { @@ -102,7 +103,8 @@ public void testAllNull() throws IOException { DateHistogramAggregationBuilder aggBuilder = new DateHistogramAggregationBuilder("histo"); aggBuilder.calendarInterval(DateHistogramInterval.DAY).field(HISTO_FIELD); - aggBuilder.subAggregation(new CardinalityAggregationBuilder("the_cardinality", ValueType.NUMERIC).field("foo")); + aggBuilder.subAggregation(new CardinalityAggregationBuilder("the_cardinality").userValueTypeHint(ValueType.NUMERIC) + .field("foo")); aggBuilder.subAggregation(new CumulativeCardinalityPipelineAggregationBuilder("cumulative_card", "the_cardinality")); executeTestCase(query, aggBuilder, histogram -> { diff --git a/x-pack/plugin/analytics/src/test/java/org/elasticsearch/xpack/analytics/stringstats/StringStatsAggregatorTests.java b/x-pack/plugin/analytics/src/test/java/org/elasticsearch/xpack/analytics/stringstats/StringStatsAggregatorTests.java index ff4bae131dd8a..4e796201cbc72 100644 --- a/x-pack/plugin/analytics/src/test/java/org/elasticsearch/xpack/analytics/stringstats/StringStatsAggregatorTests.java +++ b/x-pack/plugin/analytics/src/test/java/org/elasticsearch/xpack/analytics/stringstats/StringStatsAggregatorTests.java @@ -206,9 +206,10 @@ public void testNestedAggregation() throws IOException { textFieldType.setName("text"); textFieldType.setFielddata(true); - TermsAggregationBuilder aggregationBuilder = new TermsAggregationBuilder("terms", ValueType.NUMERIC) + TermsAggregationBuilder aggregationBuilder = new TermsAggregationBuilder("terms") + .userValueTypeHint(ValueType.NUMERIC) .field("value") - .subAggregation(new StringStatsAggregationBuilder("text_stats").field("text").valueType(ValueType.STRING)); + .subAggregation(new StringStatsAggregationBuilder("text_stats").field("text").userValueTypeHint(ValueType.STRING)); Directory directory = newDirectory(); RandomIndexWriter indexWriter = new RandomIndexWriter(random(), directory); 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 fd482f93ba827..ad31af9111db1 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 @@ -16,7 +16,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.support.ValueType; import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder; import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory; import org.elasticsearch.search.aggregations.support.ValuesSourceConfig; @@ -43,14 +42,14 @@ protected AggregationBuilder shallowCopy(Builder factoriesBuilder, Map translateTerms(TermsAggregationBuilder s return translateVSAggBuilder(source, registry, () -> { TermsAggregationBuilder rolledTerms - = new TermsAggregationBuilder(source.getName(), source.valueType()); + = new TermsAggregationBuilder(source.getName()); + if (source.userValueTypeHint() != null) { + rolledTerms.userValueTypeHint(source.userValueTypeHint()); + } rolledTerms.field(RollupField.formatFieldName(source, RollupField.VALUE)); rolledTerms.includeExclude(source.includeExclude()); if (source.collectMode() != null) { diff --git a/x-pack/plugin/rollup/src/main/java/org/elasticsearch/xpack/rollup/job/RollupIndexer.java b/x-pack/plugin/rollup/src/main/java/org/elasticsearch/xpack/rollup/job/RollupIndexer.java index 9bd5e5b6ff9b9..b70b355665e23 100644 --- a/x-pack/plugin/rollup/src/main/java/org/elasticsearch/xpack/rollup/job/RollupIndexer.java +++ b/x-pack/plugin/rollup/src/main/java/org/elasticsearch/xpack/rollup/job/RollupIndexer.java @@ -26,7 +26,6 @@ import org.elasticsearch.search.aggregations.metrics.MinAggregationBuilder; import org.elasticsearch.search.aggregations.metrics.SumAggregationBuilder; import org.elasticsearch.search.aggregations.metrics.ValueCountAggregationBuilder; -import org.elasticsearch.search.aggregations.support.ValueType; import org.elasticsearch.search.aggregations.support.ValuesSourceAggregationBuilder; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.xpack.core.indexing.AsyncTwoPhaseIndexer; @@ -282,16 +281,17 @@ static List createAggregationBuilders(final List caps = new HashSet<>(2); caps.add(cap); diff --git a/x-pack/plugin/rollup/src/test/java/org/elasticsearch/xpack/rollup/RollupRequestTranslationTests.java b/x-pack/plugin/rollup/src/test/java/org/elasticsearch/xpack/rollup/RollupRequestTranslationTests.java index cd169c1ae7ce1..0ca0cbb16ddbc 100644 --- a/x-pack/plugin/rollup/src/test/java/org/elasticsearch/xpack/rollup/RollupRequestTranslationTests.java +++ b/x-pack/plugin/rollup/src/test/java/org/elasticsearch/xpack/rollup/RollupRequestTranslationTests.java @@ -62,7 +62,7 @@ public void testBasicDateHisto() { .extendedBounds(new ExtendedBounds(0L, 1000L)) .subAggregation(new MaxAggregationBuilder("the_max").field("max_field")) .subAggregation(new AvgAggregationBuilder("the_avg").field("avg_field")); - + List translated = translateAggregation(histo, namedWriteableRegistry); assertThat(translated.size(), equalTo(1)); assertThat(translated.get(0), Matchers.instanceOf(DateHistogramAggregationBuilder.class)); @@ -302,7 +302,7 @@ public void testAvgMetric() { public void testStringTerms() throws IOException { - TermsAggregationBuilder terms = new TermsAggregationBuilder("test_string_terms", ValueType.STRING); + TermsAggregationBuilder terms = new TermsAggregationBuilder("test_string_terms").userValueTypeHint(ValueType.STRING); terms.field("foo") .subAggregation(new MaxAggregationBuilder("the_max").field("max_field")) .subAggregation(new AvgAggregationBuilder("the_avg").field("avg_field")); diff --git a/x-pack/plugin/rollup/src/test/java/org/elasticsearch/xpack/rollup/RollupResponseTranslationTests.java b/x-pack/plugin/rollup/src/test/java/org/elasticsearch/xpack/rollup/RollupResponseTranslationTests.java index 91953295bd523..01c9bc257cbcf 100644 --- a/x-pack/plugin/rollup/src/test/java/org/elasticsearch/xpack/rollup/RollupResponseTranslationTests.java +++ b/x-pack/plugin/rollup/src/test/java/org/elasticsearch/xpack/rollup/RollupResponseTranslationTests.java @@ -445,7 +445,7 @@ public void testUnsupportedMultiBucket() throws IOException { .must(QueryBuilders.termQuery("field", "foo")) .should(QueryBuilders.termQuery("field", "bar")); SignificantTermsAggregationBuilder builder = new SignificantTermsAggregationBuilder( - "test", ValueType.STRING) + "test") .field("field") .backgroundFilter(filter); @@ -1010,9 +1010,11 @@ public void testMetric() throws IOException { public void testUnsupportedMetric() throws IOException { - AggregationBuilder nonRollup = new CardinalityAggregationBuilder("test_metric", ValueType.LONG).field("foo"); + AggregationBuilder nonRollup = new CardinalityAggregationBuilder("test_metric").userValueTypeHint(ValueType.LONG) + .field("foo"); String fieldName = "foo.max." + RollupField.VALUE; - AggregationBuilder rollup = new CardinalityAggregationBuilder("test_metric", ValueType.LONG).field(fieldName); + AggregationBuilder rollup = new CardinalityAggregationBuilder("test_metric").userValueTypeHint(ValueType.LONG) + .field(fieldName); NumberFieldMapper.Builder nrValueMapper = new NumberFieldMapper.Builder("foo", NumberFieldMapper.NumberType.LONG); @@ -1044,10 +1046,10 @@ public void testUnsupportedMetric() throws IOException { } public void testStringTerms() throws IOException { - TermsAggregationBuilder nonRollupTerms = new TermsAggregationBuilder("terms", ValueType.STRING) + TermsAggregationBuilder nonRollupTerms = new TermsAggregationBuilder("terms").userValueTypeHint(ValueType.STRING) .field("stringField"); - TermsAggregationBuilder rollupTerms = new TermsAggregationBuilder("terms", ValueType.STRING) + TermsAggregationBuilder rollupTerms = new TermsAggregationBuilder("terms").userValueTypeHint(ValueType.STRING) .field("stringfield.terms." + RollupField.VALUE) .subAggregation(new SumAggregationBuilder("terms." + RollupField.COUNT_FIELD) .field("stringfield.terms." + RollupField.COUNT_FIELD)); @@ -1085,10 +1087,10 @@ public void testStringTerms() throws IOException { } public void testStringTermsNullValue() throws IOException { - TermsAggregationBuilder nonRollupTerms = new TermsAggregationBuilder("terms", ValueType.STRING) + TermsAggregationBuilder nonRollupTerms = new TermsAggregationBuilder("terms").userValueTypeHint(ValueType.STRING) .field("stringField"); - TermsAggregationBuilder rollupTerms = new TermsAggregationBuilder("terms", ValueType.STRING) + TermsAggregationBuilder rollupTerms = new TermsAggregationBuilder("terms").userValueTypeHint(ValueType.STRING) .field("stringfield.terms." + RollupField.VALUE) .subAggregation(new SumAggregationBuilder("terms." + RollupField.COUNT_FIELD) .field("stringfield.terms." + RollupField.COUNT_FIELD)); @@ -1133,10 +1135,10 @@ public void testStringTermsNullValue() throws IOException { } public void testLongTerms() throws IOException { - TermsAggregationBuilder nonRollupTerms = new TermsAggregationBuilder("terms", ValueType.LONG) + TermsAggregationBuilder nonRollupTerms = new TermsAggregationBuilder("terms").userValueTypeHint(ValueType.LONG) .field("longField"); - TermsAggregationBuilder rollupTerms = new TermsAggregationBuilder("terms", ValueType.LONG) + TermsAggregationBuilder rollupTerms = new TermsAggregationBuilder("terms").userValueTypeHint(ValueType.LONG) .field("longfield.terms." + RollupField.VALUE) .subAggregation(new SumAggregationBuilder("terms." + RollupField.COUNT_FIELD) .field("longfield.terms." + RollupField.COUNT_FIELD));