Skip to content

Commit 369ad60

Browse files
authored
Remove generics and target value type from MultiVSAB (#51647)
1 parent 2466938 commit 369ad60

8 files changed

+86
-93
lines changed

server/src/main/java/org/elasticsearch/search/aggregations/metrics/WeightedAvgAggregationBuilder.java

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,20 @@
3131
import org.elasticsearch.search.aggregations.AggregationBuilder;
3232
import org.elasticsearch.search.aggregations.AggregatorFactories.Builder;
3333
import org.elasticsearch.search.aggregations.AggregatorFactory;
34+
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
3435
import org.elasticsearch.search.aggregations.support.MultiValuesSourceAggregationBuilder;
3536
import org.elasticsearch.search.aggregations.support.MultiValuesSourceAggregatorFactory;
3637
import org.elasticsearch.search.aggregations.support.MultiValuesSourceFieldConfig;
3738
import org.elasticsearch.search.aggregations.support.MultiValuesSourceParseHelper;
3839
import org.elasticsearch.search.aggregations.support.ValueType;
39-
import org.elasticsearch.search.aggregations.support.ValuesSource.Numeric;
4040
import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
41+
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
4142

4243
import java.io.IOException;
4344
import java.util.Map;
4445
import java.util.Objects;
4546

46-
public class WeightedAvgAggregationBuilder extends MultiValuesSourceAggregationBuilder.LeafOnly<Numeric, WeightedAvgAggregationBuilder> {
47+
public class WeightedAvgAggregationBuilder extends MultiValuesSourceAggregationBuilder.LeafOnly<WeightedAvgAggregationBuilder> {
4748
public static final String NAME = "weighted_avg";
4849
public static final ParseField VALUE_FIELD = new ParseField("value");
4950
public static final ParseField WEIGHT_FIELD = new ParseField("weight");
@@ -61,7 +62,7 @@ public static AggregationBuilder parse(String aggregationName, XContentParser pa
6162
}
6263

6364
public WeightedAvgAggregationBuilder(String name) {
64-
super(name, ValueType.NUMERIC);
65+
super(name);
6566
}
6667

6768
public WeightedAvgAggregationBuilder(WeightedAvgAggregationBuilder clone, Builder factoriesBuilder, Map<String, Object> metaData) {
@@ -84,25 +85,30 @@ public WeightedAvgAggregationBuilder weight(MultiValuesSourceFieldConfig weightC
8485
* Read from a stream.
8586
*/
8687
public WeightedAvgAggregationBuilder(StreamInput in) throws IOException {
87-
super(in, ValueType.NUMERIC);
88+
super(in);
8889
}
8990

9091
@Override
9192
protected AggregationBuilder shallowCopy(Builder factoriesBuilder, Map<String, Object> metaData) {
9293
return new WeightedAvgAggregationBuilder(this, factoriesBuilder, metaData);
9394
}
9495

96+
@Override
97+
protected ValuesSourceType defaultValueSourceType() {
98+
return CoreValuesSourceType.NUMERIC;
99+
}
100+
95101
@Override
96102
protected void innerWriteTo(StreamOutput out) {
97103
// Do nothing, no extra state to write to stream
98104
}
99105

100106
@Override
101-
protected MultiValuesSourceAggregatorFactory<Numeric> innerBuild(QueryShardContext queryShardContext,
102-
Map<String, ValuesSourceConfig> configs,
103-
DocValueFormat format,
104-
AggregatorFactory parent,
105-
Builder subFactoriesBuilder) throws IOException {
107+
protected MultiValuesSourceAggregatorFactory innerBuild(QueryShardContext queryShardContext,
108+
Map<String, ValuesSourceConfig> configs,
109+
DocValueFormat format,
110+
AggregatorFactory parent,
111+
Builder subFactoriesBuilder) throws IOException {
106112
return new WeightedAvgAggregatorFactory(name, configs, format, queryShardContext, parent, subFactoriesBuilder, metaData);
107113
}
108114

server/src/main/java/org/elasticsearch/search/aggregations/metrics/WeightedAvgAggregatorFactory.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,14 @@
2727
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
2828
import org.elasticsearch.search.aggregations.support.MultiValuesSource;
2929
import org.elasticsearch.search.aggregations.support.MultiValuesSourceAggregatorFactory;
30-
import org.elasticsearch.search.aggregations.support.ValuesSource.Numeric;
3130
import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
3231
import org.elasticsearch.search.internal.SearchContext;
3332

3433
import java.io.IOException;
3534
import java.util.List;
3635
import java.util.Map;
3736

38-
class WeightedAvgAggregatorFactory extends MultiValuesSourceAggregatorFactory<Numeric> {
37+
class WeightedAvgAggregatorFactory extends MultiValuesSourceAggregatorFactory {
3938

4039
WeightedAvgAggregatorFactory(String name, Map<String, ValuesSourceConfig> configs,
4140
DocValueFormat format, QueryShardContext queryShardContext, AggregatorFactory parent,

server/src/main/java/org/elasticsearch/search/aggregations/support/MultiValuesSourceAggregationBuilder.java

Lines changed: 47 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,18 @@
4040
*
4141
* A limitation of this class is that all the ValuesSource's being refereenced must be of the same type.
4242
*/
43-
public abstract class MultiValuesSourceAggregationBuilder<VS extends ValuesSource, AB extends MultiValuesSourceAggregationBuilder<VS, AB>>
43+
public abstract class MultiValuesSourceAggregationBuilder<AB extends MultiValuesSourceAggregationBuilder<AB>>
4444
extends AbstractAggregationBuilder<AB> {
4545

4646

47-
public abstract static class LeafOnly<VS extends ValuesSource, AB extends MultiValuesSourceAggregationBuilder<VS, AB>>
48-
extends MultiValuesSourceAggregationBuilder<VS, AB> {
47+
public abstract static class LeafOnly<AB extends MultiValuesSourceAggregationBuilder<AB>>
48+
extends MultiValuesSourceAggregationBuilder<AB> {
4949

50-
protected LeafOnly(String name, ValueType targetValueType) {
51-
super(name, targetValueType);
50+
protected LeafOnly(String name) {
51+
super(name);
5252
}
5353

54-
protected LeafOnly(LeafOnly<VS, AB> clone, Builder factoriesBuilder, Map<String, Object> metaData) {
54+
protected LeafOnly(LeafOnly<AB> clone, Builder factoriesBuilder, Map<String, Object> metaData) {
5555
super(clone, factoriesBuilder, metaData);
5656
if (factoriesBuilder.count() > 0) {
5757
throw new AggregationInitializationException("Aggregator [" + name + "] of type ["
@@ -62,8 +62,8 @@ protected LeafOnly(LeafOnly<VS, AB> clone, Builder factoriesBuilder, Map<String,
6262
/**
6363
* Read from a stream that does not serialize its targetValueType. This should be used by most subclasses.
6464
*/
65-
protected LeafOnly(StreamInput in, ValueType targetValueType) throws IOException {
66-
super(in, targetValueType);
65+
protected LeafOnly(StreamInput in) throws IOException {
66+
super(in);
6767
}
6868

6969
@Override
@@ -76,30 +76,28 @@ public AB subAggregations(Builder subFactories) {
7676

7777

7878
private Map<String, MultiValuesSourceFieldConfig> fields = new HashMap<>();
79-
private final ValueType targetValueType;
80-
private ValueType valueType = null;
79+
private ValueType userValueTypeHint = null;
8180
private String format = null;
8281

83-
protected MultiValuesSourceAggregationBuilder(String name, ValueType targetValueType) {
82+
protected MultiValuesSourceAggregationBuilder(String name) {
8483
super(name);
85-
this.targetValueType = targetValueType;
8684
}
8785

88-
protected MultiValuesSourceAggregationBuilder(MultiValuesSourceAggregationBuilder<VS, AB> clone,
86+
protected MultiValuesSourceAggregationBuilder(MultiValuesSourceAggregationBuilder<AB> clone,
8987
Builder factoriesBuilder, Map<String, Object> metaData) {
9088
super(clone, factoriesBuilder, metaData);
9189

9290
this.fields = new HashMap<>(clone.fields);
93-
this.targetValueType = clone.targetValueType;
94-
this.valueType = clone.valueType;
91+
this.userValueTypeHint = clone.userValueTypeHint;
9592
this.format = clone.format;
9693
}
9794

98-
protected MultiValuesSourceAggregationBuilder(StreamInput in, ValueType targetValueType)
95+
/**
96+
* Read from a stream.
97+
*/
98+
protected MultiValuesSourceAggregationBuilder(StreamInput in)
9999
throws IOException {
100100
super(in);
101-
assert false == serializeTargetValueType() : "Wrong read constructor called for subclass that provides its targetValueType";
102-
this.targetValueType = targetValueType;
103101
read(in);
104102
}
105103

@@ -109,17 +107,14 @@ protected MultiValuesSourceAggregationBuilder(StreamInput in, ValueType targetVa
109107
@SuppressWarnings("unchecked")
110108
private void read(StreamInput in) throws IOException {
111109
fields = in.readMap(StreamInput::readString, MultiValuesSourceFieldConfig::new);
112-
valueType = in.readOptionalWriteable(ValueType::readFromStream);
110+
userValueTypeHint = in.readOptionalWriteable(ValueType::readFromStream);
113111
format = in.readOptionalString();
114112
}
115113

116114
@Override
117115
protected final void doWriteTo(StreamOutput out) throws IOException {
118-
if (serializeTargetValueType()) {
119-
out.writeOptionalWriteable(targetValueType);
120-
}
121116
out.writeMap(fields, StreamOutput::writeString, (o, value) -> value.writeTo(o));
122-
out.writeOptionalWriteable(valueType);
117+
out.writeOptionalWriteable(userValueTypeHint);
123118
out.writeOptionalString(format);
124119
innerWriteTo(out);
125120
}
@@ -142,11 +137,11 @@ protected AB field(String propertyName, MultiValuesSourceFieldConfig config) {
142137
* Sets the {@link ValueType} for the value produced by this aggregation
143138
*/
144139
@SuppressWarnings("unchecked")
145-
public AB valueType(ValueType valueType) {
140+
public AB userValueTypeHint(ValueType valueType) {
146141
if (valueType == null) {
147-
throw new IllegalArgumentException("[valueType] must not be null: [" + name + "]");
142+
throw new IllegalArgumentException("[userValueTypeHint] must not be null: [" + name + "]");
148143
}
149-
this.valueType = valueType;
144+
this.userValueTypeHint = valueType;
150145
return (AB) this;
151146
}
152147

@@ -162,25 +157,34 @@ public AB format(String format) {
162157
return (AB) this;
163158
}
164159

165-
@Override
166-
protected final MultiValuesSourceAggregatorFactory<VS> doBuild(QueryShardContext queryShardContext, AggregatorFactory parent,
167-
Builder subFactoriesBuilder) throws IOException {
168-
ValueType finalValueType = this.valueType != null ? this.valueType : targetValueType;
160+
/**
161+
* Aggregations should use this method to define a {@link ValuesSourceType} of last resort. This will only be used when the resolver
162+
* can't find a field and the user hasn't provided a value type hint.
163+
*
164+
* @return The CoreValuesSourceType we expect this script to yield.
165+
*/
166+
protected abstract ValuesSourceType defaultValueSourceType();
169167

168+
@Override
169+
protected final MultiValuesSourceAggregatorFactory doBuild(QueryShardContext queryShardContext, AggregatorFactory parent,
170+
Builder subFactoriesBuilder) throws IOException {
170171
Map<String, ValuesSourceConfig> configs = new HashMap<>(fields.size());
171172
fields.forEach((key, value) -> {
172-
ValuesSourceConfig config = ValuesSourceConfig.resolve(queryShardContext, finalValueType,
173-
value.getFieldName(), value.getScript(), value.getMissing(), value.getTimeZone(), format, getType());
173+
ValuesSourceConfig config = ValuesSourceConfig.resolve(queryShardContext, userValueTypeHint,
174+
value.getFieldName(), value.getScript(), value.getMissing(), value.getTimeZone(), format, defaultValueSourceType(),
175+
getType());
174176
configs.put(key, config);
175177
});
176-
DocValueFormat docValueFormat = resolveFormat(format, finalValueType);
178+
DocValueFormat docValueFormat = resolveFormat(format, userValueTypeHint, defaultValueSourceType());
177179
return innerBuild(queryShardContext, configs, docValueFormat, parent, subFactoriesBuilder);
178180
}
179181

180182

181-
private static DocValueFormat resolveFormat(@Nullable String format, @Nullable ValueType valueType) {
183+
private static DocValueFormat resolveFormat(@Nullable String format, @Nullable ValueType valueType,
184+
ValuesSourceType defaultValuesSourceType) {
182185
if (valueType == null) {
183-
return DocValueFormat.RAW; // we can't figure it out
186+
// If the user didn't send a hint, all we can do is fall back to the default
187+
return defaultValuesSourceType.getFormatter(format, null);
184188
}
185189
DocValueFormat valueFormat = valueType.defaultFormat;
186190
if (valueFormat instanceof DocValueFormat.Decimal && format != null) {
@@ -189,19 +193,11 @@ private static DocValueFormat resolveFormat(@Nullable String format, @Nullable V
189193
return valueFormat;
190194
}
191195

192-
protected abstract MultiValuesSourceAggregatorFactory<VS> innerBuild(QueryShardContext queryShardContext,
193-
Map<String, ValuesSourceConfig> configs,
194-
DocValueFormat format, AggregatorFactory parent,
195-
Builder subFactoriesBuilder) throws IOException;
196-
196+
protected abstract MultiValuesSourceAggregatorFactory innerBuild(QueryShardContext queryShardContext,
197+
Map<String, ValuesSourceConfig> configs,
198+
DocValueFormat format, AggregatorFactory parent,
199+
Builder subFactoriesBuilder) throws IOException;
197200

198-
/**
199-
* Should this builder serialize its targetValueType? Defaults to false. All subclasses that override this to true
200-
* should use the three argument read constructor rather than the four argument version.
201-
*/
202-
protected boolean serializeTargetValueType() {
203-
return false;
204-
}
205201

206202
@Override
207203
public final XContentBuilder internalXContent(XContentBuilder builder, Params params) throws IOException {
@@ -214,8 +210,8 @@ public final XContentBuilder internalXContent(XContentBuilder builder, Params pa
214210
if (format != null) {
215211
builder.field(CommonFields.FORMAT.getPreferredName(), format);
216212
}
217-
if (valueType != null) {
218-
builder.field(CommonFields.VALUE_TYPE.getPreferredName(), valueType.getPreferredName());
213+
if (userValueTypeHint != null) {
214+
builder.field(CommonFields.VALUE_TYPE.getPreferredName(), userValueTypeHint.getPreferredName());
219215
}
220216
doXContentBody(builder, params);
221217
builder.endObject();
@@ -226,7 +222,7 @@ public final XContentBuilder internalXContent(XContentBuilder builder, Params pa
226222

227223
@Override
228224
public int hashCode() {
229-
return Objects.hash(super.hashCode(), fields, format, targetValueType, valueType);
225+
return Objects.hash(super.hashCode(), fields, format, userValueTypeHint);
230226
}
231227

232228

@@ -239,6 +235,6 @@ public boolean equals(Object obj) {
239235
MultiValuesSourceAggregationBuilder other = (MultiValuesSourceAggregationBuilder) obj;
240236
return Objects.equals(this.fields, other.fields)
241237
&& Objects.equals(this.format, other.format)
242-
&& Objects.equals(this.valueType, other.valueType);
238+
&& Objects.equals(this.userValueTypeHint, other.userValueTypeHint);
243239
}
244240
}

server/src/main/java/org/elasticsearch/search/aggregations/support/MultiValuesSourceAggregatorFactory.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@
3131
import java.util.List;
3232
import java.util.Map;
3333

34-
public abstract class MultiValuesSourceAggregatorFactory<VS extends ValuesSource>
35-
extends AggregatorFactory {
34+
public abstract class MultiValuesSourceAggregatorFactory extends AggregatorFactory {
3635

3736
protected final Map<String, ValuesSourceConfig> configs;
3837
protected final DocValueFormat format;

server/src/main/java/org/elasticsearch/search/aggregations/support/MultiValuesSourceParseHelper.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@
2828
public final class MultiValuesSourceParseHelper {
2929

3030
public static <VS extends ValuesSource, T> void declareCommon(
31-
AbstractObjectParser<? extends MultiValuesSourceAggregationBuilder<VS, ?>, T> objectParser, boolean formattable,
32-
ValueType expectedValueType) {
31+
AbstractObjectParser<? extends MultiValuesSourceAggregationBuilder<?>, T> objectParser, boolean formattable,
32+
ValueType expectedValueType) {
3333

34-
objectParser.declareField(MultiValuesSourceAggregationBuilder::valueType, p -> {
34+
objectParser.declareField(MultiValuesSourceAggregationBuilder::userValueTypeHint, p -> {
3535
ValueType valueType = ValueType.resolveForScript(p.text());
3636
if (expectedValueType != null && valueType.isNotA(expectedValueType)) {
3737
throw new ParsingException(p.getTokenLocation(),
@@ -49,7 +49,7 @@ public static <VS extends ValuesSource, T> void declareCommon(
4949
}
5050

5151
public static <VS extends ValuesSource, T> void declareField(String fieldName,
52-
AbstractObjectParser<? extends MultiValuesSourceAggregationBuilder<VS, ?>, T> objectParser,
52+
AbstractObjectParser<? extends MultiValuesSourceAggregationBuilder<?>, T> objectParser,
5353
boolean scriptable, boolean timezoneAware) {
5454

5555
objectParser.declareField((o, fieldConfig) -> o.field(fieldName, fieldConfig.build()),

0 commit comments

Comments
 (0)