Skip to content

Commit 8f63bb2

Browse files
committed
Preparing ValuesSourceAggregatorFactory/Parser for refactoring
This change adds AbstractValuesSourceParser which will be the new class used to create ValuesSourceAggregatorFactory objects. AbstractValuesSourceParser parses all the parameters required for ValuesSource and passes to the sub-class to parse any other (implementation specific) parameters. After parsing is complete it will call createFactory on the implementing class to create the AggregatorFactory object and then set the ValuesSource specific parameters before returning it. ValuesSourceAggregatorFactory also now has setter methods so that it can be used as the 'builder' object in the future.
1 parent 81ceee1 commit 8f63bb2

File tree

10 files changed

+273
-63
lines changed

10 files changed

+273
-63
lines changed

core/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/DateHistogramParser.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -189,10 +189,6 @@ public AggregatorFactory parse(String aggregationName, XContentParser parser, Se
189189
.timeZone(vsParser.input().timezone())
190190
.offset(offset).build();
191191

192-
ValuesSourceConfig config = vsParser.config();
193-
if (config.formatter()!=null) {
194-
((DateTime) config.formatter()).setTimeZone(timeZone);
195-
}
196192
ValuesSourceParser.Input input = vsParser.input();
197193
return new HistogramAggregator.DateHistogramFactory(aggregationName, input, rounding, order, keyed, minDocCount, extendedBounds,
198194
new InternalDateHistogram.Factory());

core/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/HistogramAggregator.java

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory;
3939
import org.elasticsearch.search.aggregations.support.ValuesSourceParser;
4040
import org.elasticsearch.search.aggregations.support.format.ValueFormatter;
41-
import org.elasticsearch.search.aggregations.support.format.ValueFormatter.DateTime;
4241
import org.joda.time.DateTimeZone;
4342

4443
import java.io.IOException;
@@ -206,32 +205,23 @@ public static class DateHistogramFactory extends Factory {
206205
private DateTimeZone timeZone;
207206

208207
public DateHistogramFactory(String name, ValuesSourceParser.Input<Numeric> input, Rounding rounding, InternalOrder order,
209-
boolean keyed, long minDocCount, ExtendedBounds extendedBounds,
210-
org.elasticsearch.search.aggregations.bucket.histogram.InternalHistogram.Factory<?> histogramFactory, DateTimeZone timeZone) {
208+
boolean keyed, long minDocCount, ExtendedBounds extendedBounds, InternalHistogram.Factory<?> histogramFactory) {
211209
super(name, input, rounding, order, keyed, minDocCount, extendedBounds, histogramFactory);
212-
this.timeZone = timeZone;
210+
this.timeZone = input.timezone();
213211
}
214212

215213
@Override
216214
protected Aggregator createUnmapped(AggregationContext aggregationContext, Aggregator parent,
217215
List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData) throws IOException {
218-
setFormatterTimeZone();
219216
return super.createUnmapped(aggregationContext, parent, pipelineAggregators, metaData);
220217
}
221218

222219
@Override
223220
protected Aggregator doCreateInternal(Numeric valuesSource, AggregationContext aggregationContext, Aggregator parent,
224221
boolean collectsFromSingleBucket, List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData)
225222
throws IOException {
226-
setFormatterTimeZone();
227223
return super
228224
.doCreateInternal(valuesSource, aggregationContext, parent, collectsFromSingleBucket, pipelineAggregators, metaData);
229225
}
230-
231-
private void setFormatterTimeZone() {
232-
if (config.formatter() instanceof ValueFormatter.DateTime) {
233-
((DateTime) config.formatter()).setTimeZone(timeZone);
234-
}
235-
}
236226
}
237227
}

core/src/main/java/org/elasticsearch/search/aggregations/metrics/cardinality/CardinalityAggregatorFactory.java

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919

2020
package org.elasticsearch.search.aggregations.metrics.cardinality;
2121

22-
import org.elasticsearch.index.mapper.core.Murmur3FieldMapper;
23-
import org.elasticsearch.search.aggregations.AggregationExecutionException;
2422
import org.elasticsearch.search.aggregations.Aggregator;
2523
import org.elasticsearch.search.aggregations.bucket.SingleBucketAggregator;
2624
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
@@ -49,19 +47,9 @@ private int precision(Aggregator parent) {
4947
@Override
5048
protected Aggregator createUnmapped(AggregationContext context, Aggregator parent, List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData)
5149
throws IOException {
52-
resolveRehash();
5350
return new CardinalityAggregator(name, null, precision(parent), config.formatter(), context, parent, pipelineAggregators, metaData);
5451
}
5552

56-
private void resolveRehash() {
57-
if (rehash == null && config.fieldContext() != null
58-
&& config.fieldContext().fieldType() instanceof Murmur3FieldMapper.Murmur3FieldType) {
59-
rehash = false;
60-
} else if (rehash == null) {
61-
rehash = true;
62-
}
63-
}
64-
6553
@Override
6654
protected Aggregator doCreateInternal(ValuesSource valuesSource, AggregationContext context, Aggregator parent,
6755
boolean collectsFromSingleBucket, List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData) throws IOException {

core/src/main/java/org/elasticsearch/search/aggregations/metrics/cardinality/CardinalityParser.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.elasticsearch.search.SearchParseException;
2525
import org.elasticsearch.search.aggregations.Aggregator;
2626
import org.elasticsearch.search.aggregations.AggregatorFactory;
27+
import org.elasticsearch.search.aggregations.support.ValuesSource;
2728
import org.elasticsearch.search.aggregations.support.ValuesSourceParser;
2829
import org.elasticsearch.search.internal.SearchContext;
2930

core/src/main/java/org/elasticsearch/search/aggregations/metrics/percentiles/PercentilesParser.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public String type() {
4949
protected ParseField keysField() {
5050
return PERCENTS_FIELD;
5151
}
52-
52+
5353
@Override
5454
protected AggregatorFactory buildFactory(SearchContext context, String aggregationName, ValuesSourceParser.Input<Numeric> valuesSourceInput,
5555
double[] keys, PercentilesMethod method, Double compression, Integer numberOfSignificantValueDigits, boolean keyed) {
@@ -59,7 +59,7 @@ protected AggregatorFactory buildFactory(SearchContext context, String aggregati
5959
if (method == PercentilesMethod.TDIGEST) {
6060
return new TDigestPercentilesAggregator.Factory(aggregationName, valuesSourceInput, keys, compression, keyed);
6161
} else if (method == PercentilesMethod.HDR) {
62-
return new HDRPercentilesAggregator.Factory(aggregationName, valuesSourceConfig, keys, numberOfSignificantValueDigits, keyed);
62+
return new HDRPercentilesAggregator.Factory(aggregationName, valuesSourceInput, keys, numberOfSignificantValueDigits, keyed);
6363
} else {
6464
throw new AssertionError();
6565
}

core/src/main/java/org/elasticsearch/search/aggregations/metrics/percentiles/hdr/HDRPercentileRanksAggregator.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
import org.elasticsearch.search.aggregations.support.ValuesSource;
2727
import org.elasticsearch.search.aggregations.support.ValuesSource.Numeric;
2828
import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory;
29-
import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
29+
import org.elasticsearch.search.aggregations.support.ValuesSourceParser;
3030
import org.elasticsearch.search.aggregations.support.format.ValueFormatter;
3131

3232
import java.io.IOException;
@@ -80,9 +80,9 @@ public static class Factory extends ValuesSourceAggregatorFactory.LeafOnly<Value
8080
private final int numberOfSignificantValueDigits;
8181
private final boolean keyed;
8282

83-
public Factory(String name, ValuesSourceConfig<ValuesSource.Numeric> valuesSourceConfig, double[] values,
83+
public Factory(String name, ValuesSourceParser.Input<ValuesSource.Numeric> valuesSourceInput, double[] values,
8484
int numberOfSignificantValueDigits, boolean keyed) {
85-
super(name, InternalHDRPercentiles.TYPE.name(), valuesSourceConfig);
85+
super(name, InternalHDRPercentiles.TYPE.name(), valuesSourceInput);
8686
this.values = values;
8787
this.numberOfSignificantValueDigits = numberOfSignificantValueDigits;
8888
this.keyed = keyed;

core/src/main/java/org/elasticsearch/search/aggregations/metrics/percentiles/hdr/HDRPercentilesAggregator.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
import org.elasticsearch.search.aggregations.support.ValuesSource;
2828
import org.elasticsearch.search.aggregations.support.ValuesSource.Numeric;
2929
import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory;
30-
import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
30+
import org.elasticsearch.search.aggregations.support.ValuesSourceParser;
3131
import org.elasticsearch.search.aggregations.support.format.ValueFormatter;
3232

3333
import java.io.IOException;
@@ -82,9 +82,9 @@ public static class Factory extends ValuesSourceAggregatorFactory.LeafOnly<Value
8282
private final int numberOfSignificantValueDigits;
8383
private final boolean keyed;
8484

85-
public Factory(String name, ValuesSourceConfig<ValuesSource.Numeric> valuesSourceConfig, double[] percents,
85+
public Factory(String name, ValuesSourceParser.Input<ValuesSource.Numeric> valuesSourceInput, double[] percents,
8686
int numberOfSignificantValueDigits, boolean keyed) {
87-
super(name, InternalTDigestPercentiles.TYPE.name(), valuesSourceConfig);
87+
super(name, InternalTDigestPercentiles.TYPE.name(), valuesSourceInput);
8888
this.percents = percents;
8989
this.numberOfSignificantValueDigits = numberOfSignificantValueDigits;
9090
this.keyed = keyed;
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.search.aggregations.support;
21+
22+
import org.elasticsearch.common.xcontent.XContentParser;
23+
import org.elasticsearch.script.Script;
24+
import org.elasticsearch.script.Script.ScriptField;
25+
import org.elasticsearch.script.ScriptParameterParser;
26+
import org.elasticsearch.script.ScriptParameterParser.ScriptParameterValue;
27+
import org.elasticsearch.search.SearchParseException;
28+
import org.elasticsearch.search.aggregations.Aggregator;
29+
import org.elasticsearch.search.aggregations.AggregatorFactory;
30+
import org.elasticsearch.search.internal.SearchContext;
31+
32+
import java.io.IOException;
33+
import java.util.Map;
34+
35+
import static com.google.common.collect.Maps.newHashMap;
36+
37+
/**
38+
*
39+
*/
40+
public abstract class AbstractValuesSourceParser<VS extends ValuesSource> implements Aggregator.Parser {
41+
42+
public abstract static class AnyValuesSourceParser extends AbstractValuesSourceParser<ValuesSource> {
43+
44+
protected AnyValuesSourceParser(boolean scriptable, boolean formattable) {
45+
super(scriptable, formattable, ValuesSource.class, null);
46+
}
47+
}
48+
49+
public abstract static class NumericValuesSourceParser extends AbstractValuesSourceParser<ValuesSource.Numeric> {
50+
51+
protected NumericValuesSourceParser(boolean scriptable, boolean formattable) {
52+
super(scriptable, formattable, ValuesSource.Numeric.class, ValueType.NUMERIC);
53+
}
54+
}
55+
56+
public abstract static class BytesValuesSourceParser extends AbstractValuesSourceParser<ValuesSource.Bytes> {
57+
58+
protected BytesValuesSourceParser(boolean scriptable, boolean formattable) {
59+
super(scriptable, formattable, ValuesSource.Bytes.class, ValueType.STRING);
60+
}
61+
}
62+
63+
public abstract static class GeoPointValuesSourceParser extends AbstractValuesSourceParser<ValuesSource.GeoPoint> {
64+
65+
protected GeoPointValuesSourceParser(boolean scriptable, boolean formattable) {
66+
super(scriptable, formattable, ValuesSource.GeoPoint.class, ValueType.GEOPOINT);
67+
}
68+
}
69+
70+
private boolean scriptable = true;
71+
private boolean formattable = false;
72+
private Class<VS> valuesSourceType = null;
73+
private ValueType targetValueType = null;
74+
private ScriptParameterParser scriptParameterParser = new ScriptParameterParser();
75+
76+
private AbstractValuesSourceParser(boolean scriptable,
77+
boolean formattable, Class<VS> valuesSourceType, ValueType targetValueType) {
78+
this.valuesSourceType = valuesSourceType;
79+
this.targetValueType = targetValueType;
80+
this.scriptable = scriptable;
81+
this.formattable = formattable;
82+
}
83+
84+
@Override
85+
public AggregatorFactory parse(String aggregationName, XContentParser parser, SearchContext context) throws IOException {
86+
87+
String field = null;
88+
Script script = null;
89+
@Deprecated
90+
Map<String, Object> params = null; // TODO Remove in 3.0
91+
ValueType valueType = null;
92+
String format = null;
93+
Object missing = null;
94+
95+
XContentParser.Token token;
96+
String currentFieldName = null;
97+
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
98+
if (token == XContentParser.Token.FIELD_NAME) {
99+
currentFieldName = parser.currentName();
100+
} else if ("missing".equals(currentFieldName) && token.isValue()) {
101+
missing = parser.objectText();
102+
} else if (token == XContentParser.Token.VALUE_STRING) {
103+
if ("field".equals(currentFieldName)) {
104+
field = parser.text();
105+
} else if (formattable && "format".equals(currentFieldName)) {
106+
format = parser.text();
107+
} else if (scriptable) {
108+
if ("value_type".equals(currentFieldName) || "valueType".equals(currentFieldName)) {
109+
valueType = ValueType.resolveForScript(parser.text());
110+
if (targetValueType != null && valueType.isNotA(targetValueType)) {
111+
throw new SearchParseException(context, type() + " aggregation [" + aggregationName
112+
+ "] was configured with an incompatible value type [" + valueType + "]. [" + type()
113+
+ "] aggregation can only work on value of type [" + targetValueType + "]",
114+
parser.getTokenLocation());
115+
}
116+
} else if (!scriptParameterParser.token(currentFieldName, token, parser, context.parseFieldMatcher())) {
117+
throw new SearchParseException(context, "Unexpected token " + token + " in [" + aggregationName + "].",
118+
parser.getTokenLocation());
119+
}
120+
} else {
121+
throw new SearchParseException(context, "Unexpected token " + token + " in [" + aggregationName + "].",
122+
parser.getTokenLocation());
123+
}
124+
} else if (scriptable && token == XContentParser.Token.START_OBJECT) {
125+
if (context.parseFieldMatcher().match(currentFieldName, ScriptField.SCRIPT)) {
126+
script = Script.parse(parser, context.parseFieldMatcher());
127+
} else if ("params".equals(currentFieldName)) {
128+
params = parser.map();
129+
} else {
130+
throw new SearchParseException(context, "Unexpected token " + token + " in [" + aggregationName + "].",
131+
parser.getTokenLocation());
132+
}
133+
} else if (!token(currentFieldName, token, parser)) {
134+
throw new SearchParseException(context, "Unexpected token " + token + " in [" + aggregationName + "].",
135+
parser.getTokenLocation());
136+
}
137+
}
138+
139+
if (script == null) { // Didn't find anything using the new API so
140+
// try using the old one instead
141+
ScriptParameterValue scriptValue = scriptParameterParser.getDefaultScriptParameterValue();
142+
if (scriptValue != null) {
143+
if (params == null) {
144+
params = newHashMap();
145+
}
146+
script = new Script(scriptValue.script(), scriptValue.scriptType(), scriptParameterParser.lang(), params);
147+
}
148+
}
149+
150+
ValuesSourceAggregatorFactory<VS> factory = createFactory(aggregationName, this.valuesSourceType, this.targetValueType);
151+
factory.field(field);
152+
factory.script(script);
153+
factory.valueType(valueType);
154+
factory.format(format);
155+
factory.missing(missing);
156+
return factory;
157+
}
158+
159+
protected abstract ValuesSourceAggregatorFactory<VS> createFactory(String aggregationName, Class<VS> valuesSourceType,
160+
ValueType targetValueType);
161+
162+
protected abstract boolean token(String currentFieldName, XContentParser.Token token, XContentParser parser) throws IOException;
163+
}

0 commit comments

Comments
 (0)