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.
This commit is contained in:
parent
7a3f6fc1ba
commit
855c199f60
|
@ -189,10 +189,6 @@ public class DateHistogramParser implements Aggregator.Parser {
|
||||||
.timeZone(vsParser.input().timezone())
|
.timeZone(vsParser.input().timezone())
|
||||||
.offset(offset).build();
|
.offset(offset).build();
|
||||||
|
|
||||||
ValuesSourceConfig config = vsParser.config();
|
|
||||||
if (config.formatter()!=null) {
|
|
||||||
((DateTime) config.formatter()).setTimeZone(timeZone);
|
|
||||||
}
|
|
||||||
ValuesSourceParser.Input input = vsParser.input();
|
ValuesSourceParser.Input input = vsParser.input();
|
||||||
return new HistogramAggregator.DateHistogramFactory(aggregationName, input, rounding, order, keyed, minDocCount, extendedBounds,
|
return new HistogramAggregator.DateHistogramFactory(aggregationName, input, rounding, order, keyed, minDocCount, extendedBounds,
|
||||||
new InternalDateHistogram.Factory());
|
new InternalDateHistogram.Factory());
|
||||||
|
|
|
@ -38,7 +38,6 @@ import org.elasticsearch.search.aggregations.support.ValuesSource.Numeric;
|
||||||
import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory;
|
import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory;
|
||||||
import org.elasticsearch.search.aggregations.support.ValuesSourceParser;
|
import org.elasticsearch.search.aggregations.support.ValuesSourceParser;
|
||||||
import org.elasticsearch.search.aggregations.support.format.ValueFormatter;
|
import org.elasticsearch.search.aggregations.support.format.ValueFormatter;
|
||||||
import org.elasticsearch.search.aggregations.support.format.ValueFormatter.DateTime;
|
|
||||||
import org.joda.time.DateTimeZone;
|
import org.joda.time.DateTimeZone;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -206,16 +205,14 @@ public class HistogramAggregator extends BucketsAggregator {
|
||||||
private DateTimeZone timeZone;
|
private DateTimeZone timeZone;
|
||||||
|
|
||||||
public DateHistogramFactory(String name, ValuesSourceParser.Input<Numeric> input, Rounding rounding, InternalOrder order,
|
public DateHistogramFactory(String name, ValuesSourceParser.Input<Numeric> input, Rounding rounding, InternalOrder order,
|
||||||
boolean keyed, long minDocCount, ExtendedBounds extendedBounds,
|
boolean keyed, long minDocCount, ExtendedBounds extendedBounds, InternalHistogram.Factory<?> histogramFactory) {
|
||||||
org.elasticsearch.search.aggregations.bucket.histogram.InternalHistogram.Factory<?> histogramFactory, DateTimeZone timeZone) {
|
|
||||||
super(name, input, rounding, order, keyed, minDocCount, extendedBounds, histogramFactory);
|
super(name, input, rounding, order, keyed, minDocCount, extendedBounds, histogramFactory);
|
||||||
this.timeZone = timeZone;
|
this.timeZone = input.timezone();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Aggregator createUnmapped(AggregationContext aggregationContext, Aggregator parent,
|
protected Aggregator createUnmapped(AggregationContext aggregationContext, Aggregator parent,
|
||||||
List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData) throws IOException {
|
List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData) throws IOException {
|
||||||
setFormatterTimeZone();
|
|
||||||
return super.createUnmapped(aggregationContext, parent, pipelineAggregators, metaData);
|
return super.createUnmapped(aggregationContext, parent, pipelineAggregators, metaData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,15 +220,8 @@ public class HistogramAggregator extends BucketsAggregator {
|
||||||
protected Aggregator doCreateInternal(Numeric valuesSource, AggregationContext aggregationContext, Aggregator parent,
|
protected Aggregator doCreateInternal(Numeric valuesSource, AggregationContext aggregationContext, Aggregator parent,
|
||||||
boolean collectsFromSingleBucket, List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData)
|
boolean collectsFromSingleBucket, List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
setFormatterTimeZone();
|
|
||||||
return super
|
return super
|
||||||
.doCreateInternal(valuesSource, aggregationContext, parent, collectsFromSingleBucket, pipelineAggregators, metaData);
|
.doCreateInternal(valuesSource, aggregationContext, parent, collectsFromSingleBucket, pipelineAggregators, metaData);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setFormatterTimeZone() {
|
|
||||||
if (config.formatter() instanceof ValueFormatter.DateTime) {
|
|
||||||
((DateTime) config.formatter()).setTimeZone(timeZone);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,6 @@
|
||||||
|
|
||||||
package org.elasticsearch.search.aggregations.metrics.cardinality;
|
package org.elasticsearch.search.aggregations.metrics.cardinality;
|
||||||
|
|
||||||
import org.elasticsearch.index.mapper.core.Murmur3FieldMapper;
|
|
||||||
import org.elasticsearch.search.aggregations.AggregationExecutionException;
|
|
||||||
import org.elasticsearch.search.aggregations.Aggregator;
|
import org.elasticsearch.search.aggregations.Aggregator;
|
||||||
import org.elasticsearch.search.aggregations.bucket.SingleBucketAggregator;
|
import org.elasticsearch.search.aggregations.bucket.SingleBucketAggregator;
|
||||||
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
|
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
|
||||||
|
@ -49,19 +47,9 @@ final class CardinalityAggregatorFactory extends ValuesSourceAggregatorFactory.L
|
||||||
@Override
|
@Override
|
||||||
protected Aggregator createUnmapped(AggregationContext context, Aggregator parent, List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData)
|
protected Aggregator createUnmapped(AggregationContext context, Aggregator parent, List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
resolveRehash();
|
|
||||||
return new CardinalityAggregator(name, null, precision(parent), config.formatter(), context, parent, pipelineAggregators, metaData);
|
return new CardinalityAggregator(name, null, precision(parent), config.formatter(), context, parent, pipelineAggregators, metaData);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resolveRehash() {
|
|
||||||
if (rehash == null && config.fieldContext() != null
|
|
||||||
&& config.fieldContext().fieldType() instanceof Murmur3FieldMapper.Murmur3FieldType) {
|
|
||||||
rehash = false;
|
|
||||||
} else if (rehash == null) {
|
|
||||||
rehash = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Aggregator doCreateInternal(ValuesSource valuesSource, AggregationContext context, Aggregator parent,
|
protected Aggregator doCreateInternal(ValuesSource valuesSource, AggregationContext context, Aggregator parent,
|
||||||
boolean collectsFromSingleBucket, List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData) throws IOException {
|
boolean collectsFromSingleBucket, List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData) throws IOException {
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.search.SearchParseException;
|
import org.elasticsearch.search.SearchParseException;
|
||||||
import org.elasticsearch.search.aggregations.Aggregator;
|
import org.elasticsearch.search.aggregations.Aggregator;
|
||||||
import org.elasticsearch.search.aggregations.AggregatorFactory;
|
import org.elasticsearch.search.aggregations.AggregatorFactory;
|
||||||
|
import org.elasticsearch.search.aggregations.support.ValuesSource;
|
||||||
import org.elasticsearch.search.aggregations.support.ValuesSourceParser;
|
import org.elasticsearch.search.aggregations.support.ValuesSourceParser;
|
||||||
import org.elasticsearch.search.internal.SearchContext;
|
import org.elasticsearch.search.internal.SearchContext;
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ public class PercentilesParser extends AbstractPercentilesParser {
|
||||||
if (method == PercentilesMethod.TDIGEST) {
|
if (method == PercentilesMethod.TDIGEST) {
|
||||||
return new TDigestPercentilesAggregator.Factory(aggregationName, valuesSourceInput, keys, compression, keyed);
|
return new TDigestPercentilesAggregator.Factory(aggregationName, valuesSourceInput, keys, compression, keyed);
|
||||||
} else if (method == PercentilesMethod.HDR) {
|
} else if (method == PercentilesMethod.HDR) {
|
||||||
return new HDRPercentilesAggregator.Factory(aggregationName, valuesSourceConfig, keys, numberOfSignificantValueDigits, keyed);
|
return new HDRPercentilesAggregator.Factory(aggregationName, valuesSourceInput, keys, numberOfSignificantValueDigits, keyed);
|
||||||
} else {
|
} else {
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ import org.elasticsearch.search.aggregations.support.AggregationContext;
|
||||||
import org.elasticsearch.search.aggregations.support.ValuesSource;
|
import org.elasticsearch.search.aggregations.support.ValuesSource;
|
||||||
import org.elasticsearch.search.aggregations.support.ValuesSource.Numeric;
|
import org.elasticsearch.search.aggregations.support.ValuesSource.Numeric;
|
||||||
import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory;
|
import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory;
|
||||||
import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
|
import org.elasticsearch.search.aggregations.support.ValuesSourceParser;
|
||||||
import org.elasticsearch.search.aggregations.support.format.ValueFormatter;
|
import org.elasticsearch.search.aggregations.support.format.ValueFormatter;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -80,9 +80,9 @@ public class HDRPercentileRanksAggregator extends AbstractHDRPercentilesAggregat
|
||||||
private final int numberOfSignificantValueDigits;
|
private final int numberOfSignificantValueDigits;
|
||||||
private final boolean keyed;
|
private final boolean keyed;
|
||||||
|
|
||||||
public Factory(String name, ValuesSourceConfig<ValuesSource.Numeric> valuesSourceConfig, double[] values,
|
public Factory(String name, ValuesSourceParser.Input<ValuesSource.Numeric> valuesSourceInput, double[] values,
|
||||||
int numberOfSignificantValueDigits, boolean keyed) {
|
int numberOfSignificantValueDigits, boolean keyed) {
|
||||||
super(name, InternalHDRPercentiles.TYPE.name(), valuesSourceConfig);
|
super(name, InternalHDRPercentiles.TYPE.name(), valuesSourceInput);
|
||||||
this.values = values;
|
this.values = values;
|
||||||
this.numberOfSignificantValueDigits = numberOfSignificantValueDigits;
|
this.numberOfSignificantValueDigits = numberOfSignificantValueDigits;
|
||||||
this.keyed = keyed;
|
this.keyed = keyed;
|
||||||
|
|
|
@ -27,7 +27,7 @@ import org.elasticsearch.search.aggregations.support.AggregationContext;
|
||||||
import org.elasticsearch.search.aggregations.support.ValuesSource;
|
import org.elasticsearch.search.aggregations.support.ValuesSource;
|
||||||
import org.elasticsearch.search.aggregations.support.ValuesSource.Numeric;
|
import org.elasticsearch.search.aggregations.support.ValuesSource.Numeric;
|
||||||
import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory;
|
import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory;
|
||||||
import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
|
import org.elasticsearch.search.aggregations.support.ValuesSourceParser;
|
||||||
import org.elasticsearch.search.aggregations.support.format.ValueFormatter;
|
import org.elasticsearch.search.aggregations.support.format.ValueFormatter;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -82,9 +82,9 @@ public class HDRPercentilesAggregator extends AbstractHDRPercentilesAggregator {
|
||||||
private final int numberOfSignificantValueDigits;
|
private final int numberOfSignificantValueDigits;
|
||||||
private final boolean keyed;
|
private final boolean keyed;
|
||||||
|
|
||||||
public Factory(String name, ValuesSourceConfig<ValuesSource.Numeric> valuesSourceConfig, double[] percents,
|
public Factory(String name, ValuesSourceParser.Input<ValuesSource.Numeric> valuesSourceInput, double[] percents,
|
||||||
int numberOfSignificantValueDigits, boolean keyed) {
|
int numberOfSignificantValueDigits, boolean keyed) {
|
||||||
super(name, InternalTDigestPercentiles.TYPE.name(), valuesSourceConfig);
|
super(name, InternalTDigestPercentiles.TYPE.name(), valuesSourceInput);
|
||||||
this.percents = percents;
|
this.percents = percents;
|
||||||
this.numberOfSignificantValueDigits = numberOfSignificantValueDigits;
|
this.numberOfSignificantValueDigits = numberOfSignificantValueDigits;
|
||||||
this.keyed = keyed;
|
this.keyed = keyed;
|
||||||
|
|
|
@ -0,0 +1,163 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.search.aggregations.support;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.script.Script;
|
||||||
|
import org.elasticsearch.script.Script.ScriptField;
|
||||||
|
import org.elasticsearch.script.ScriptParameterParser;
|
||||||
|
import org.elasticsearch.script.ScriptParameterParser.ScriptParameterValue;
|
||||||
|
import org.elasticsearch.search.SearchParseException;
|
||||||
|
import org.elasticsearch.search.aggregations.Aggregator;
|
||||||
|
import org.elasticsearch.search.aggregations.AggregatorFactory;
|
||||||
|
import org.elasticsearch.search.internal.SearchContext;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static com.google.common.collect.Maps.newHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class AbstractValuesSourceParser<VS extends ValuesSource> implements Aggregator.Parser {
|
||||||
|
|
||||||
|
public abstract static class AnyValuesSourceParser extends AbstractValuesSourceParser<ValuesSource> {
|
||||||
|
|
||||||
|
protected AnyValuesSourceParser(boolean scriptable, boolean formattable) {
|
||||||
|
super(scriptable, formattable, ValuesSource.class, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract static class NumericValuesSourceParser extends AbstractValuesSourceParser<ValuesSource.Numeric> {
|
||||||
|
|
||||||
|
protected NumericValuesSourceParser(boolean scriptable, boolean formattable) {
|
||||||
|
super(scriptable, formattable, ValuesSource.Numeric.class, ValueType.NUMERIC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract static class BytesValuesSourceParser extends AbstractValuesSourceParser<ValuesSource.Bytes> {
|
||||||
|
|
||||||
|
protected BytesValuesSourceParser(boolean scriptable, boolean formattable) {
|
||||||
|
super(scriptable, formattable, ValuesSource.Bytes.class, ValueType.STRING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract static class GeoPointValuesSourceParser extends AbstractValuesSourceParser<ValuesSource.GeoPoint> {
|
||||||
|
|
||||||
|
protected GeoPointValuesSourceParser(boolean scriptable, boolean formattable) {
|
||||||
|
super(scriptable, formattable, ValuesSource.GeoPoint.class, ValueType.GEOPOINT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean scriptable = true;
|
||||||
|
private boolean formattable = false;
|
||||||
|
private Class<VS> valuesSourceType = null;
|
||||||
|
private ValueType targetValueType = null;
|
||||||
|
private ScriptParameterParser scriptParameterParser = new ScriptParameterParser();
|
||||||
|
|
||||||
|
private AbstractValuesSourceParser(boolean scriptable,
|
||||||
|
boolean formattable, Class<VS> valuesSourceType, ValueType targetValueType) {
|
||||||
|
this.valuesSourceType = valuesSourceType;
|
||||||
|
this.targetValueType = targetValueType;
|
||||||
|
this.scriptable = scriptable;
|
||||||
|
this.formattable = formattable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AggregatorFactory parse(String aggregationName, XContentParser parser, SearchContext context) throws IOException {
|
||||||
|
|
||||||
|
String field = null;
|
||||||
|
Script script = null;
|
||||||
|
@Deprecated
|
||||||
|
Map<String, Object> params = null; // TODO Remove in 3.0
|
||||||
|
ValueType valueType = null;
|
||||||
|
String format = null;
|
||||||
|
Object missing = null;
|
||||||
|
|
||||||
|
XContentParser.Token token;
|
||||||
|
String currentFieldName = null;
|
||||||
|
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||||
|
if (token == XContentParser.Token.FIELD_NAME) {
|
||||||
|
currentFieldName = parser.currentName();
|
||||||
|
} else if ("missing".equals(currentFieldName) && token.isValue()) {
|
||||||
|
missing = parser.objectText();
|
||||||
|
} else if (token == XContentParser.Token.VALUE_STRING) {
|
||||||
|
if ("field".equals(currentFieldName)) {
|
||||||
|
field = parser.text();
|
||||||
|
} else if (formattable && "format".equals(currentFieldName)) {
|
||||||
|
format = parser.text();
|
||||||
|
} else if (scriptable) {
|
||||||
|
if ("value_type".equals(currentFieldName) || "valueType".equals(currentFieldName)) {
|
||||||
|
valueType = ValueType.resolveForScript(parser.text());
|
||||||
|
if (targetValueType != null && valueType.isNotA(targetValueType)) {
|
||||||
|
throw new SearchParseException(context, type() + " aggregation [" + aggregationName
|
||||||
|
+ "] was configured with an incompatible value type [" + valueType + "]. [" + type()
|
||||||
|
+ "] aggregation can only work on value of type [" + targetValueType + "]",
|
||||||
|
parser.getTokenLocation());
|
||||||
|
}
|
||||||
|
} else if (!scriptParameterParser.token(currentFieldName, token, parser, context.parseFieldMatcher())) {
|
||||||
|
throw new SearchParseException(context, "Unexpected token " + token + " in [" + aggregationName + "].",
|
||||||
|
parser.getTokenLocation());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new SearchParseException(context, "Unexpected token " + token + " in [" + aggregationName + "].",
|
||||||
|
parser.getTokenLocation());
|
||||||
|
}
|
||||||
|
} else if (scriptable && token == XContentParser.Token.START_OBJECT) {
|
||||||
|
if (context.parseFieldMatcher().match(currentFieldName, ScriptField.SCRIPT)) {
|
||||||
|
script = Script.parse(parser, context.parseFieldMatcher());
|
||||||
|
} else if ("params".equals(currentFieldName)) {
|
||||||
|
params = parser.map();
|
||||||
|
} else {
|
||||||
|
throw new SearchParseException(context, "Unexpected token " + token + " in [" + aggregationName + "].",
|
||||||
|
parser.getTokenLocation());
|
||||||
|
}
|
||||||
|
} else if (!token(currentFieldName, token, parser)) {
|
||||||
|
throw new SearchParseException(context, "Unexpected token " + token + " in [" + aggregationName + "].",
|
||||||
|
parser.getTokenLocation());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (script == null) { // Didn't find anything using the new API so
|
||||||
|
// try using the old one instead
|
||||||
|
ScriptParameterValue scriptValue = scriptParameterParser.getDefaultScriptParameterValue();
|
||||||
|
if (scriptValue != null) {
|
||||||
|
if (params == null) {
|
||||||
|
params = newHashMap();
|
||||||
|
}
|
||||||
|
script = new Script(scriptValue.script(), scriptValue.scriptType(), scriptParameterParser.lang(), params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ValuesSourceAggregatorFactory<VS> factory = createFactory(aggregationName, this.valuesSourceType, this.targetValueType);
|
||||||
|
factory.field(field);
|
||||||
|
factory.script(script);
|
||||||
|
factory.valueType(valueType);
|
||||||
|
factory.format(format);
|
||||||
|
factory.missing(missing);
|
||||||
|
return factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract ValuesSourceAggregatorFactory<VS> createFactory(String aggregationName, Class<VS> valuesSourceType,
|
||||||
|
ValueType targetValueType);
|
||||||
|
|
||||||
|
protected abstract boolean token(String currentFieldName, XContentParser.Token token, XContentParser parser) throws IOException;
|
||||||
|
}
|
|
@ -38,6 +38,7 @@ import org.elasticsearch.search.aggregations.AggregatorFactory;
|
||||||
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
|
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
|
||||||
import org.elasticsearch.search.aggregations.support.format.ValueFormat;
|
import org.elasticsearch.search.aggregations.support.format.ValueFormat;
|
||||||
import org.elasticsearch.search.internal.SearchContext;
|
import org.elasticsearch.search.internal.SearchContext;
|
||||||
|
import org.joda.time.DateTimeZone;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -54,23 +55,78 @@ public abstract class ValuesSourceAggregatorFactory<VS extends ValuesSource> ext
|
||||||
super(name, type, input);
|
super(name, type, input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected LeafOnly(String name, String type, Class<VS> valuesSourceType, ValueType targetValueType) {
|
||||||
|
super(name, type, valuesSourceType, targetValueType);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AggregatorFactory subFactories(AggregatorFactories subFactories) {
|
public AggregatorFactory subFactories(AggregatorFactories subFactories) {
|
||||||
throw new AggregationInitializationException("Aggregator [" + name + "] of type [" + type + "] cannot accept sub-aggregations");
|
throw new AggregationInitializationException("Aggregator [" + name + "] of type [" + type + "] cannot accept sub-aggregations");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final Class<VS> valuesSourceType;
|
||||||
|
private final ValueType targetValueType;
|
||||||
|
private String field = null;
|
||||||
|
private Script script = null;
|
||||||
|
private ValueType valueType = null;
|
||||||
|
private String format = null;
|
||||||
|
private Object missing = null;
|
||||||
protected ValuesSourceConfig<VS> config;
|
protected ValuesSourceConfig<VS> config;
|
||||||
private ValuesSourceParser.Input<VS> input;
|
private DateTimeZone timeZone;
|
||||||
|
|
||||||
|
// NORELEASE remove this method when aggs refactoring complete
|
||||||
|
/**
|
||||||
|
* This constructor remains here until all subclasses have been moved to the
|
||||||
|
* new constructor. This also means moving from using
|
||||||
|
* {@link ValuesSourceParser} to using {@link AbstractValuesSourceParser}.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
protected ValuesSourceAggregatorFactory(String name, String type, ValuesSourceParser.Input<VS> input) {
|
protected ValuesSourceAggregatorFactory(String name, String type, ValuesSourceParser.Input<VS> input) {
|
||||||
super(name, type);
|
super(name, type);
|
||||||
this.input = input;
|
this.valuesSourceType = input.valuesSourceType;
|
||||||
|
this.targetValueType = input.targetValueType;
|
||||||
|
this.field = input.field;
|
||||||
|
this.script = input.script;
|
||||||
|
this.valueType = input.valueType;
|
||||||
|
this.format = input.format;
|
||||||
|
this.missing = input.missing;
|
||||||
|
this.timeZone = input.timezone;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ValuesSourceAggregatorFactory(String name, String type, Class<VS> valuesSourceType, ValueType targetValueType) {
|
||||||
|
super(name, type);
|
||||||
|
this.valuesSourceType = valuesSourceType;
|
||||||
|
this.targetValueType = targetValueType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void field(String field) {
|
||||||
|
this.field = field;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void script(Script script) {
|
||||||
|
this.script = script;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void valueType(ValueType valueType) {
|
||||||
|
this.valueType = valueType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void format(String format) {
|
||||||
|
this.format = format;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void missing(Object missing) {
|
||||||
|
this.missing = missing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void timeZone(DateTimeZone timeZone) {
|
||||||
|
this.timeZone = timeZone;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doInit(AggregationContext context) {
|
public void doInit(AggregationContext context) {
|
||||||
this.config = config(input, context);
|
this.config = config(context);
|
||||||
if (config == null || !config.valid()) {
|
if (config == null || !config.valid()) {
|
||||||
resolveValuesSourceConfigFromAncestors(name, this.parent, config.valueSourceType());
|
resolveValuesSourceConfigFromAncestors(name, this.parent, config.valueSourceType());
|
||||||
}
|
}
|
||||||
|
@ -91,17 +147,17 @@ public abstract class ValuesSourceAggregatorFactory<VS extends ValuesSource> ext
|
||||||
public void doValidate() {
|
public void doValidate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValuesSourceConfig<VS> config(ValuesSourceParser.Input<VS> input, AggregationContext context) {
|
public ValuesSourceConfig<VS> config(AggregationContext context) {
|
||||||
|
|
||||||
ValueType valueType = input.valueType != null ? input.valueType : input.targetValueType;
|
ValueType valueType = this.valueType != null ? this.valueType : targetValueType;
|
||||||
|
|
||||||
if (input.field == null) {
|
if (field == null) {
|
||||||
if (input.script == null) {
|
if (script == null) {
|
||||||
ValuesSourceConfig<VS> config = new ValuesSourceConfig(ValuesSource.class);
|
ValuesSourceConfig<VS> config = new ValuesSourceConfig(ValuesSource.class);
|
||||||
config.format = resolveFormat(null, valueType);
|
config.format = resolveFormat(null, valueType);
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
Class valuesSourceType = valueType != null ? (Class<VS>) valueType.getValuesSourceType() : input.valuesSourceType;
|
Class valuesSourceType = valueType != null ? (Class<VS>) valueType.getValuesSourceType() : this.valuesSourceType;
|
||||||
if (valuesSourceType == null || valuesSourceType == ValuesSource.class) {
|
if (valuesSourceType == null || valuesSourceType == ValuesSource.class) {
|
||||||
// the specific value source type is undefined, but for scripts,
|
// the specific value source type is undefined, but for scripts,
|
||||||
// we need to have a specific value source
|
// we need to have a specific value source
|
||||||
|
@ -110,19 +166,19 @@ public abstract class ValuesSourceAggregatorFactory<VS extends ValuesSource> ext
|
||||||
valuesSourceType = ValuesSource.Bytes.class;
|
valuesSourceType = ValuesSource.Bytes.class;
|
||||||
}
|
}
|
||||||
ValuesSourceConfig<VS> config = new ValuesSourceConfig<VS>(valuesSourceType);
|
ValuesSourceConfig<VS> config = new ValuesSourceConfig<VS>(valuesSourceType);
|
||||||
config.missing = input.missing;
|
config.missing = missing;
|
||||||
config.format = resolveFormat(input.format, valueType);
|
config.format = resolveFormat(format, valueType);
|
||||||
config.script = createScript(input.script, context.searchContext());
|
config.script = createScript(script, context.searchContext());
|
||||||
config.scriptValueType = valueType;
|
config.scriptValueType = valueType;
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
MappedFieldType fieldType = context.searchContext().smartNameFieldTypeFromAnyType(input.field);
|
MappedFieldType fieldType = context.searchContext().smartNameFieldTypeFromAnyType(field);
|
||||||
if (fieldType == null) {
|
if (fieldType == null) {
|
||||||
Class<VS> valuesSourceType = valueType != null ? (Class<VS>) valueType.getValuesSourceType() : input.valuesSourceType;
|
Class<VS> valuesSourceType = valueType != null ? (Class<VS>) valueType.getValuesSourceType() : this.valuesSourceType;
|
||||||
ValuesSourceConfig<VS> config = new ValuesSourceConfig<>(valuesSourceType);
|
ValuesSourceConfig<VS> config = new ValuesSourceConfig<>(valuesSourceType);
|
||||||
config.missing = input.missing;
|
config.missing = missing;
|
||||||
config.format = resolveFormat(input.format, valueType);
|
config.format = resolveFormat(format, valueType);
|
||||||
config.unmapped = true;
|
config.unmapped = true;
|
||||||
if (valueType != null) {
|
if (valueType != null) {
|
||||||
// todo do we really need this for unmapped?
|
// todo do we really need this for unmapped?
|
||||||
|
@ -134,7 +190,7 @@ public abstract class ValuesSourceAggregatorFactory<VS extends ValuesSource> ext
|
||||||
IndexFieldData<?> indexFieldData = context.searchContext().fieldData().getForField(fieldType);
|
IndexFieldData<?> indexFieldData = context.searchContext().fieldData().getForField(fieldType);
|
||||||
|
|
||||||
ValuesSourceConfig config;
|
ValuesSourceConfig config;
|
||||||
if (input.valuesSourceType == ValuesSource.class) {
|
if (valuesSourceType == ValuesSource.class) {
|
||||||
if (indexFieldData instanceof IndexNumericFieldData) {
|
if (indexFieldData instanceof IndexNumericFieldData) {
|
||||||
config = new ValuesSourceConfig<>(ValuesSource.Numeric.class);
|
config = new ValuesSourceConfig<>(ValuesSource.Numeric.class);
|
||||||
} else if (indexFieldData instanceof IndexGeoPointFieldData) {
|
} else if (indexFieldData instanceof IndexGeoPointFieldData) {
|
||||||
|
@ -143,13 +199,13 @@ public abstract class ValuesSourceAggregatorFactory<VS extends ValuesSource> ext
|
||||||
config = new ValuesSourceConfig<>(ValuesSource.Bytes.class);
|
config = new ValuesSourceConfig<>(ValuesSource.Bytes.class);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
config = new ValuesSourceConfig(input.valuesSourceType);
|
config = new ValuesSourceConfig(valuesSourceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
config.fieldContext = new FieldContext(input.field, indexFieldData, fieldType);
|
config.fieldContext = new FieldContext(field, indexFieldData, fieldType);
|
||||||
config.missing = input.missing;
|
config.missing = missing;
|
||||||
config.script = createScript(input.script, context.searchContext());
|
config.script = createScript(script, context.searchContext());
|
||||||
config.format = resolveFormat(input.format, fieldType);
|
config.format = resolveFormat(format, this.timeZone, fieldType);
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,10 +224,10 @@ public abstract class ValuesSourceAggregatorFactory<VS extends ValuesSource> ext
|
||||||
return valueFormat;
|
return valueFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ValueFormat resolveFormat(@Nullable String format, MappedFieldType fieldType) {
|
private static ValueFormat resolveFormat(@Nullable String format, @Nullable DateTimeZone timezone, MappedFieldType fieldType) {
|
||||||
if (fieldType instanceof DateFieldMapper.DateFieldType) {
|
if (fieldType instanceof DateFieldMapper.DateFieldType) {
|
||||||
return format != null ? ValueFormat.DateTime.format(format) : ValueFormat.DateTime
|
return format != null ? ValueFormat.DateTime.format(format, timezone) : ValueFormat.DateTime.mapper(
|
||||||
.mapper((DateFieldMapper.DateFieldType) fieldType);
|
(DateFieldMapper.DateFieldType) fieldType, timezone);
|
||||||
}
|
}
|
||||||
if (fieldType instanceof IpFieldMapper.IpFieldType) {
|
if (fieldType instanceof IpFieldMapper.IpFieldType) {
|
||||||
return ValueFormat.IPv4;
|
return ValueFormat.IPv4;
|
||||||
|
@ -201,7 +257,8 @@ public abstract class ValuesSourceAggregatorFactory<VS extends ValuesSource> ext
|
||||||
if (requiredValuesSourceType == null || requiredValuesSourceType.isAssignableFrom(config.valueSourceType)) {
|
if (requiredValuesSourceType == null || requiredValuesSourceType.isAssignableFrom(config.valueSourceType)) {
|
||||||
ValueFormat format = config.format;
|
ValueFormat format = config.format;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
// if the user explicitly defined a format pattern, we'll do our best to keep it even when we inherit the
|
// if the user explicitly defined a format pattern,
|
||||||
|
// we'll do our best to keep it even when we inherit the
|
||||||
// value source form one of the ancestor aggregations
|
// value source form one of the ancestor aggregations
|
||||||
if (this.config.formatPattern != null && format != null && format instanceof ValueFormat.Patternable) {
|
if (this.config.formatPattern != null && format != null && format instanceof ValueFormat.Patternable) {
|
||||||
this.config.format = ((ValueFormat.Patternable) format).create(this.config.formatPattern);
|
this.config.format = ((ValueFormat.Patternable) format).create(this.config.formatPattern);
|
||||||
|
|
|
@ -35,9 +35,12 @@ import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
// NORELEASE remove this class when aggs refactoring complete
|
||||||
/**
|
/**
|
||||||
*
|
* @deprecated use {@link AbstractValuesSourceParser} instead. This class will
|
||||||
|
* be removed when aggs refactoring is complete.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public class ValuesSourceParser<VS extends ValuesSource> {
|
public class ValuesSourceParser<VS extends ValuesSource> {
|
||||||
|
|
||||||
static final ParseField TIME_ZONE = new ParseField("time_zone");
|
static final ParseField TIME_ZONE = new ParseField("time_zone");
|
||||||
|
@ -58,6 +61,12 @@ public class ValuesSourceParser<VS extends ValuesSource> {
|
||||||
return new Builder<>(aggName, aggType, context, ValuesSource.GeoPoint.class).targetValueType(ValueType.GEOPOINT).scriptable(false);
|
return new Builder<>(aggName, aggType, context, ValuesSource.GeoPoint.class).targetValueType(ValueType.GEOPOINT).scriptable(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NORELEASE remove this class when aggs refactoring complete
|
||||||
|
/**
|
||||||
|
* @deprecated use {@link AbstractValuesSourceParser} instead. This class
|
||||||
|
* will be removed when aggs refactoring is complete.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public static class Input<VS> {
|
public static class Input<VS> {
|
||||||
String field = null;
|
String field = null;
|
||||||
Script script = null;
|
Script script = null;
|
||||||
|
@ -68,6 +77,7 @@ public class ValuesSourceParser<VS extends ValuesSource> {
|
||||||
Object missing = null;
|
Object missing = null;
|
||||||
Class<VS> valuesSourceType = null;
|
Class<VS> valuesSourceType = null;
|
||||||
ValueType targetValueType = null;
|
ValueType targetValueType = null;
|
||||||
|
DateTimeZone timezone = DateTimeZone.UTC;
|
||||||
|
|
||||||
public boolean valid() {
|
public boolean valid() {
|
||||||
return field != null || script != null;
|
return field != null || script != null;
|
||||||
|
@ -77,7 +87,6 @@ public class ValuesSourceParser<VS extends ValuesSource> {
|
||||||
return this.timezone;
|
return this.timezone;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private final String aggName;
|
private final String aggName;
|
||||||
private final InternalAggregation.Type aggType;
|
private final InternalAggregation.Type aggType;
|
||||||
|
@ -163,6 +172,12 @@ public class ValuesSourceParser<VS extends ValuesSource> {
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NORELEASE remove this class when aggs refactoring complete
|
||||||
|
/**
|
||||||
|
* @deprecated use {@link AbstractValuesSourceParser} instead. This class
|
||||||
|
* will be removed when aggs refactoring is complete.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public static class Builder<VS extends ValuesSource> {
|
public static class Builder<VS extends ValuesSource> {
|
||||||
|
|
||||||
private final ValuesSourceParser<VS> parser;
|
private final ValuesSourceParser<VS> parser;
|
||||||
|
|
Loading…
Reference in New Issue