added validation of reducers

This commit is contained in:
Colin Goodheart-Smithe 2015-03-23 08:58:44 +00:00
parent cb4ab06021
commit b751f0e11b
7 changed files with 57 additions and 18 deletions

View File

@ -40,6 +40,7 @@ public class AggregatorFactories {
public static final AggregatorFactories EMPTY = new Empty();
private AggregatorFactory parent;
private AggregatorFactory[] factories;
private List<ReducerFactory> reducerFactories;
@ -101,6 +102,7 @@ public class AggregatorFactories {
}
void setParent(AggregatorFactory parent) {
this.parent = parent;
for (AggregatorFactory factory : factories) {
factory.parent = parent;
}
@ -111,7 +113,7 @@ public class AggregatorFactories {
factory.validate();
}
for (ReducerFactory factory : reducerFactories) {
factory.validate();
factory.validate(parent, factories, reducerFactories);
}
}

View File

@ -66,6 +66,10 @@ public abstract class AggregatorFactory {
return this;
}
public String name() {
return name;
}
/**
* Validates the state of this factory (makes sure the factory is properly configured)
*/

View File

@ -169,6 +169,10 @@ public class HistogramAggregator extends BucketsAggregator {
this.histogramFactory = histogramFactory;
}
public long minDocCount() {
return minDocCount;
}
@Override
protected Aggregator createUnmapped(AggregationContext aggregationContext, Aggregator parent, List<Reducer> reducers,
Map<String, Object> metaData) throws IOException {

View File

@ -19,9 +19,11 @@
package org.elasticsearch.search.aggregations.reducers;
import org.elasticsearch.search.aggregations.Aggregator;
import org.elasticsearch.search.aggregations.AggregatorFactory;
import org.elasticsearch.search.aggregations.support.AggregationContext;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
@ -49,10 +51,15 @@ public abstract class ReducerFactory {
}
/**
* Validates the state of this factory (makes sure the factory is properly configured)
* Validates the state of this factory (makes sure the factory is properly
* configured)
*
* @param reducerFactories
* @param factories
* @param parent
*/
public final void validate() {
doValidate();
public final void validate(AggregatorFactory parent, AggregatorFactory[] factories, List<ReducerFactory> reducerFactories) {
doValidate(parent, factories, reducerFactories);
}
protected abstract Reducer createInternal(AggregationContext context, Aggregator parent, boolean collectsFromSingleBucket,
@ -79,7 +86,7 @@ public abstract class ReducerFactory {
return aggregator;
}
public void doValidate() {
public void doValidate(AggregatorFactory parent, AggregatorFactory[] factories, List<ReducerFactory> reducerFactories) {
}
public void setMetaData(Map<String, Object> metaData) {

View File

@ -22,18 +22,24 @@ package org.elasticsearch.search.aggregations.reducers.derivative;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import org.elasticsearch.ElasticsearchIllegalStateException;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.Aggregator;
import org.elasticsearch.search.aggregations.AggregatorFactory;
import org.elasticsearch.search.aggregations.InternalAggregation;
import org.elasticsearch.search.aggregations.InternalAggregation.ReduceContext;
import org.elasticsearch.search.aggregations.InternalAggregation.Type;
import org.elasticsearch.search.aggregations.InternalAggregations;
import org.elasticsearch.search.aggregations.bucket.histogram.HistogramAggregator;
import org.elasticsearch.search.aggregations.bucket.histogram.InternalHistogram;
import org.elasticsearch.search.aggregations.reducers.*;
import org.elasticsearch.search.aggregations.reducers.BucketHelpers.GapPolicy;
import org.elasticsearch.search.aggregations.reducers.InternalSimpleValue;
import org.elasticsearch.search.aggregations.reducers.Reducer;
import org.elasticsearch.search.aggregations.reducers.ReducerFactory;
import org.elasticsearch.search.aggregations.reducers.ReducerStreams;
import org.elasticsearch.search.aggregations.support.AggregationContext;
import org.elasticsearch.search.aggregations.support.format.ValueFormatter;
import org.elasticsearch.search.aggregations.support.format.ValueFormatterStreams;
@ -43,7 +49,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static org.elasticsearch.search.aggregations.reducers.BucketHelpers.GapPolicy;
import static org.elasticsearch.search.aggregations.reducers.BucketHelpers.resolveBucketValue;
public class DerivativeReducer extends Reducer {
@ -143,5 +148,23 @@ public class DerivativeReducer extends Reducer {
return new DerivativeReducer(name, bucketsPaths, formatter, gapPolicy, metaData);
}
@Override
public void doValidate(AggregatorFactory parent, AggregatorFactory[] aggFactories, List<ReducerFactory> reducerFactories) {
if (bucketsPaths.length != 1) {
throw new ElasticsearchIllegalStateException(Reducer.Parser.BUCKETS_PATH.getPreferredName()
+ " must contain a single entry for reducer [" + name + "]");
}
if (!(parent instanceof HistogramAggregator.Factory)) {
throw new ElasticsearchIllegalStateException("derivative reducer [" + name
+ "] must have a histogram or date_histogram as parent");
} else {
HistogramAggregator.Factory histoParent = (HistogramAggregator.Factory) parent;
if (histoParent.minDocCount() != 0) {
throw new ElasticsearchIllegalStateException("parent histogram of derivative reducer [" + name
+ "] must have min_doc_count of 0");
}
}
}
}
}

View File

@ -109,7 +109,7 @@ public class DateDerivativeTests extends ElasticsearchIntegrationTest {
SearchResponse response = client()
.prepareSearch("idx")
.addAggregation(
dateHistogram("histo").field("date").interval(DateHistogramInterval.MONTH)
dateHistogram("histo").field("date").interval(DateHistogramInterval.MONTH).minDocCount(0)
.subAggregation(derivative("deriv").setBucketsPaths("_count"))).execute().actionGet();
assertSearchResponse(response);
@ -152,7 +152,7 @@ public class DateDerivativeTests extends ElasticsearchIntegrationTest {
SearchResponse response = client()
.prepareSearch("idx")
.addAggregation(
dateHistogram("histo").field("date").interval(DateHistogramInterval.MONTH)
dateHistogram("histo").field("date").interval(DateHistogramInterval.MONTH).minDocCount(0)
.subAggregation(derivative("deriv").setBucketsPaths("sum")).subAggregation(sum("sum").field("value")))
.execute().actionGet();
@ -222,7 +222,7 @@ public class DateDerivativeTests extends ElasticsearchIntegrationTest {
SearchResponse response = client()
.prepareSearch("idx")
.addAggregation(
dateHistogram("histo").field("dates").interval(DateHistogramInterval.MONTH)
dateHistogram("histo").field("dates").interval(DateHistogramInterval.MONTH).minDocCount(0)
.subAggregation(derivative("deriv").setBucketsPaths("_count"))).execute().actionGet();
assertSearchResponse(response);
@ -278,7 +278,7 @@ public class DateDerivativeTests extends ElasticsearchIntegrationTest {
SearchResponse response = client()
.prepareSearch("idx_unmapped")
.addAggregation(
dateHistogram("histo").field("date").interval(DateHistogramInterval.MONTH)
dateHistogram("histo").field("date").interval(DateHistogramInterval.MONTH).minDocCount(0)
.subAggregation(derivative("deriv").setBucketsPaths("_count"))).execute().actionGet();
assertSearchResponse(response);
@ -294,7 +294,7 @@ public class DateDerivativeTests extends ElasticsearchIntegrationTest {
SearchResponse response = client()
.prepareSearch("idx", "idx_unmapped")
.addAggregation(
dateHistogram("histo").field("date").interval(DateHistogramInterval.MONTH)
dateHistogram("histo").field("date").interval(DateHistogramInterval.MONTH).minDocCount(0)
.subAggregation(derivative("deriv").setBucketsPaths("_count"))).execute().actionGet();
assertSearchResponse(response);

View File

@ -34,7 +34,6 @@ import org.junit.Test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
@ -165,7 +164,7 @@ public class DerivativeTests extends ElasticsearchIntegrationTest {
SearchResponse response = client()
.prepareSearch("idx")
.addAggregation(
histogram("histo").field(SINGLE_VALUED_FIELD_NAME).interval(interval)
histogram("histo").field(SINGLE_VALUED_FIELD_NAME).interval(interval).minDocCount(0)
.subAggregation(derivative("deriv").setBucketsPaths("_count"))
.subAggregation(derivative("2nd_deriv").setBucketsPaths("deriv"))).execute().actionGet();
@ -202,7 +201,7 @@ public class DerivativeTests extends ElasticsearchIntegrationTest {
SearchResponse response = client()
.prepareSearch("idx")
.addAggregation(
histogram("histo").field(SINGLE_VALUED_FIELD_NAME).interval(interval)
histogram("histo").field(SINGLE_VALUED_FIELD_NAME).interval(interval).minDocCount(0)
.subAggregation(sum("sum").field(SINGLE_VALUED_FIELD_NAME))
.subAggregation(derivative("deriv").setBucketsPaths("sum"))).execute().actionGet();
@ -248,7 +247,7 @@ public class DerivativeTests extends ElasticsearchIntegrationTest {
SearchResponse response = client()
.prepareSearch("idx_unmapped")
.addAggregation(
histogram("histo").field(SINGLE_VALUED_FIELD_NAME).interval(interval)
histogram("histo").field(SINGLE_VALUED_FIELD_NAME).interval(interval).minDocCount(0)
.subAggregation(derivative("deriv").setBucketsPaths("_count"))).execute().actionGet();
assertSearchResponse(response);
@ -264,7 +263,7 @@ public class DerivativeTests extends ElasticsearchIntegrationTest {
SearchResponse response = client()
.prepareSearch("idx", "idx_unmapped")
.addAggregation(
histogram("histo").field(SINGLE_VALUED_FIELD_NAME).interval(interval)
histogram("histo").field(SINGLE_VALUED_FIELD_NAME).interval(interval).minDocCount(0)
.subAggregation(derivative("deriv").setBucketsPaths("_count"))).execute().actionGet();
assertSearchResponse(response);