|
@@ -59,17 +59,18 @@ import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
|
|
import org.elasticsearch.indices.breaker.NoneCircuitBreakerService;
|
|
|
import org.elasticsearch.indices.fielddata.cache.IndicesFieldDataCache;
|
|
|
import org.elasticsearch.mock.orig.Mockito;
|
|
|
+import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation;
|
|
|
import org.elasticsearch.search.fetch.FetchPhase;
|
|
|
import org.elasticsearch.search.fetch.subphase.DocValueFieldsFetchSubPhase;
|
|
|
import org.elasticsearch.search.fetch.subphase.FetchSourceSubPhase;
|
|
|
import org.elasticsearch.search.internal.ContextIndexSearcher;
|
|
|
import org.elasticsearch.search.internal.SearchContext;
|
|
|
import org.elasticsearch.search.lookup.SearchLookup;
|
|
|
+import org.elasticsearch.search.aggregations.MultiBucketConsumerService.MultiBucketConsumer;
|
|
|
import org.elasticsearch.test.ESTestCase;
|
|
|
+import org.elasticsearch.test.InternalAggregationTestCase;
|
|
|
import org.junit.After;
|
|
|
import org.mockito.Matchers;
|
|
|
-import org.mockito.invocation.InvocationOnMock;
|
|
|
-import org.mockito.stubbing.Answer;
|
|
|
|
|
|
import java.io.IOException;
|
|
|
import java.util.ArrayList;
|
|
@@ -82,6 +83,7 @@ import static org.mockito.Matchers.anyString;
|
|
|
import static org.mockito.Mockito.doAnswer;
|
|
|
import static org.mockito.Mockito.mock;
|
|
|
import static org.mockito.Mockito.when;
|
|
|
+import static org.elasticsearch.test.InternalAggregationTestCase.DEFAULT_MAX_BUCKETS;
|
|
|
|
|
|
/**
|
|
|
* Base class for testing {@link Aggregator} implementations.
|
|
@@ -96,16 +98,20 @@ public abstract class AggregatorTestCase extends ESTestCase {
|
|
|
protected AggregatorFactory<?> createAggregatorFactory(AggregationBuilder aggregationBuilder,
|
|
|
IndexSearcher indexSearcher,
|
|
|
MappedFieldType... fieldTypes) throws IOException {
|
|
|
- return createAggregatorFactory(aggregationBuilder, indexSearcher, createIndexSettings(), fieldTypes);
|
|
|
+ return createAggregatorFactory(aggregationBuilder, indexSearcher, createIndexSettings(),
|
|
|
+ new MultiBucketConsumer(DEFAULT_MAX_BUCKETS), fieldTypes);
|
|
|
}
|
|
|
|
|
|
/** Create a factory for the given aggregation builder. */
|
|
|
protected AggregatorFactory<?> createAggregatorFactory(AggregationBuilder aggregationBuilder,
|
|
|
IndexSearcher indexSearcher,
|
|
|
IndexSettings indexSettings,
|
|
|
+ MultiBucketConsumer bucketConsumer,
|
|
|
MappedFieldType... fieldTypes) throws IOException {
|
|
|
SearchContext searchContext = createSearchContext(indexSearcher, indexSettings);
|
|
|
CircuitBreakerService circuitBreakerService = new NoneCircuitBreakerService();
|
|
|
+ when(searchContext.aggregations())
|
|
|
+ .thenReturn(new SearchContextAggregations(AggregatorFactories.EMPTY, bucketConsumer));
|
|
|
when(searchContext.bigArrays()).thenReturn(new MockBigArrays(Settings.EMPTY, circuitBreakerService));
|
|
|
// TODO: now just needed for top_hits, this will need to be revised for other agg unit tests:
|
|
|
MapperService mapperService = mapperServiceMock();
|
|
@@ -116,12 +122,8 @@ public abstract class AggregatorTestCase extends ESTestCase {
|
|
|
IndexFieldDataService ifds = new IndexFieldDataService(indexSettings,
|
|
|
new IndicesFieldDataCache(Settings.EMPTY, new IndexFieldDataCache.Listener() {
|
|
|
}), circuitBreakerService, mapperService);
|
|
|
- when(searchContext.getForField(Mockito.any(MappedFieldType.class))).thenAnswer(new Answer<Object>() {
|
|
|
- @Override
|
|
|
- public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
|
|
|
- return ifds.getForField((MappedFieldType) invocationOnMock.getArguments()[0]);
|
|
|
- }
|
|
|
- });
|
|
|
+ when(searchContext.getForField(Mockito.any(MappedFieldType.class)))
|
|
|
+ .thenAnswer(invocationOnMock -> ifds.getForField((MappedFieldType) invocationOnMock.getArguments()[0]));
|
|
|
|
|
|
SearchLookup searchLookup = new SearchLookup(mapperService, ifds::getForField, new String[]{TYPE_NAME});
|
|
|
when(searchContext.lookup()).thenReturn(searchLookup);
|
|
@@ -139,15 +141,32 @@ public abstract class AggregatorTestCase extends ESTestCase {
|
|
|
protected <A extends Aggregator> A createAggregator(AggregationBuilder aggregationBuilder,
|
|
|
IndexSearcher indexSearcher,
|
|
|
MappedFieldType... fieldTypes) throws IOException {
|
|
|
- return createAggregator(aggregationBuilder, indexSearcher, createIndexSettings(), fieldTypes);
|
|
|
+ return createAggregator(aggregationBuilder, indexSearcher, createIndexSettings(),
|
|
|
+ new MultiBucketConsumer(DEFAULT_MAX_BUCKETS), fieldTypes);
|
|
|
}
|
|
|
|
|
|
protected <A extends Aggregator> A createAggregator(AggregationBuilder aggregationBuilder,
|
|
|
IndexSearcher indexSearcher,
|
|
|
IndexSettings indexSettings,
|
|
|
MappedFieldType... fieldTypes) throws IOException {
|
|
|
+ return createAggregator(aggregationBuilder, indexSearcher, indexSettings,
|
|
|
+ new MultiBucketConsumer(DEFAULT_MAX_BUCKETS), fieldTypes);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected <A extends Aggregator> A createAggregator(AggregationBuilder aggregationBuilder,
|
|
|
+ IndexSearcher indexSearcher,
|
|
|
+ MultiBucketConsumer bucketConsumer,
|
|
|
+ MappedFieldType... fieldTypes) throws IOException {
|
|
|
+ return createAggregator(aggregationBuilder, indexSearcher, createIndexSettings(), bucketConsumer, fieldTypes);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected <A extends Aggregator> A createAggregator(AggregationBuilder aggregationBuilder,
|
|
|
+ IndexSearcher indexSearcher,
|
|
|
+ IndexSettings indexSettings,
|
|
|
+ MultiBucketConsumer bucketConsumer,
|
|
|
+ MappedFieldType... fieldTypes) throws IOException {
|
|
|
@SuppressWarnings("unchecked")
|
|
|
- A aggregator = (A) createAggregatorFactory(aggregationBuilder, indexSearcher, indexSettings, fieldTypes)
|
|
|
+ A aggregator = (A) createAggregatorFactory(aggregationBuilder, indexSearcher, indexSettings, bucketConsumer, fieldTypes)
|
|
|
.create(null, true);
|
|
|
return aggregator;
|
|
|
}
|
|
@@ -233,24 +252,33 @@ public abstract class AggregatorTestCase extends ESTestCase {
|
|
|
Query query,
|
|
|
AggregationBuilder builder,
|
|
|
MappedFieldType... fieldTypes) throws IOException {
|
|
|
- return search(searcher, query, builder, createIndexSettings(), fieldTypes);
|
|
|
+ return search(searcher, query, builder, DEFAULT_MAX_BUCKETS, fieldTypes);
|
|
|
}
|
|
|
|
|
|
protected <A extends InternalAggregation, C extends Aggregator> A search(IndexSearcher searcher,
|
|
|
Query query,
|
|
|
AggregationBuilder builder,
|
|
|
- IndexSettings indexSettings,
|
|
|
+ int maxBucket,
|
|
|
MappedFieldType... fieldTypes) throws IOException {
|
|
|
- C a = createAggregator(builder, searcher, fieldTypes);
|
|
|
+ MultiBucketConsumer bucketConsumer = new MultiBucketConsumer(maxBucket);
|
|
|
+ C a = createAggregator(builder, searcher, bucketConsumer, fieldTypes);
|
|
|
a.preCollection();
|
|
|
searcher.search(query, a);
|
|
|
a.postCollection();
|
|
|
@SuppressWarnings("unchecked")
|
|
|
A internalAgg = (A) a.buildAggregation(0L);
|
|
|
+ InternalAggregationTestCase.assertMultiBucketConsumer(internalAgg, bucketConsumer);
|
|
|
return internalAgg;
|
|
|
|
|
|
}
|
|
|
|
|
|
+ protected <A extends InternalAggregation, C extends Aggregator> A searchAndReduce(IndexSearcher searcher,
|
|
|
+ Query query,
|
|
|
+ AggregationBuilder builder,
|
|
|
+ MappedFieldType... fieldTypes) throws IOException {
|
|
|
+ return searchAndReduce(searcher, query, builder, DEFAULT_MAX_BUCKETS, fieldTypes);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Divides the provided {@link IndexSearcher} in sub-searcher, one for each segment,
|
|
|
* builds an aggregator for each sub-searcher filtered by the provided {@link Query} and
|
|
@@ -259,6 +287,7 @@ public abstract class AggregatorTestCase extends ESTestCase {
|
|
|
protected <A extends InternalAggregation, C extends Aggregator> A searchAndReduce(IndexSearcher searcher,
|
|
|
Query query,
|
|
|
AggregationBuilder builder,
|
|
|
+ int maxBucket,
|
|
|
MappedFieldType... fieldTypes) throws IOException {
|
|
|
final IndexReaderContext ctx = searcher.getTopReaderContext();
|
|
|
|
|
@@ -279,14 +308,18 @@ public abstract class AggregatorTestCase extends ESTestCase {
|
|
|
List<InternalAggregation> aggs = new ArrayList<> ();
|
|
|
Query rewritten = searcher.rewrite(query);
|
|
|
Weight weight = searcher.createWeight(rewritten, true, 1f);
|
|
|
- C root = createAggregator(builder, searcher, fieldTypes);
|
|
|
+ MultiBucketConsumer bucketConsumer = new MultiBucketConsumer(maxBucket);
|
|
|
+ C root = createAggregator(builder, searcher, bucketConsumer, fieldTypes);
|
|
|
|
|
|
for (ShardSearcher subSearcher : subSearchers) {
|
|
|
- C a = createAggregator(builder, subSearcher, fieldTypes);
|
|
|
+ MultiBucketConsumer shardBucketConsumer = new MultiBucketConsumer(maxBucket);
|
|
|
+ C a = createAggregator(builder, subSearcher, shardBucketConsumer, fieldTypes);
|
|
|
a.preCollection();
|
|
|
subSearcher.search(weight, a);
|
|
|
a.postCollection();
|
|
|
- aggs.add(a.buildAggregation(0L));
|
|
|
+ InternalAggregation agg = a.buildAggregation(0L);
|
|
|
+ aggs.add(agg);
|
|
|
+ InternalAggregationTestCase.assertMultiBucketConsumer(agg, shardBucketConsumer);
|
|
|
}
|
|
|
if (aggs.isEmpty()) {
|
|
|
return null;
|
|
@@ -297,15 +330,23 @@ public abstract class AggregatorTestCase extends ESTestCase {
|
|
|
Collections.shuffle(aggs, random());
|
|
|
int r = randomIntBetween(1, toReduceSize);
|
|
|
List<InternalAggregation> toReduce = aggs.subList(0, r);
|
|
|
- A reduced = (A) aggs.get(0).doReduce(toReduce,
|
|
|
- new InternalAggregation.ReduceContext(root.context().bigArrays(), null, false));
|
|
|
+ MultiBucketConsumer reduceBucketConsumer = new MultiBucketConsumer(maxBucket);
|
|
|
+ InternalAggregation.ReduceContext context =
|
|
|
+ new InternalAggregation.ReduceContext(root.context().bigArrays(), null,
|
|
|
+ reduceBucketConsumer, false);
|
|
|
+ A reduced = (A) aggs.get(0).doReduce(toReduce, context);
|
|
|
+ InternalAggregationTestCase.assertMultiBucketConsumer(reduced, reduceBucketConsumer);
|
|
|
aggs = new ArrayList<>(aggs.subList(r, toReduceSize));
|
|
|
aggs.add(reduced);
|
|
|
}
|
|
|
// now do the final reduce
|
|
|
+ MultiBucketConsumer reduceBucketConsumer = new MultiBucketConsumer(maxBucket);
|
|
|
+ InternalAggregation.ReduceContext context =
|
|
|
+ new InternalAggregation.ReduceContext(root.context().bigArrays(), null, reduceBucketConsumer, true);
|
|
|
+
|
|
|
@SuppressWarnings("unchecked")
|
|
|
- A internalAgg = (A) aggs.get(0).doReduce(aggs, new InternalAggregation.ReduceContext(root.context().bigArrays(), null,
|
|
|
- true));
|
|
|
+ A internalAgg = (A) aggs.get(0).doReduce(aggs, context);
|
|
|
+ InternalAggregationTestCase.assertMultiBucketConsumer(internalAgg, reduceBucketConsumer);
|
|
|
return internalAgg;
|
|
|
}
|
|
|
|