Skip to content

Commit 29463c4

Browse files
authored
Vs refactor wire up ranges and date ranges (#52918)
1 parent 33fc002 commit 29463c4

File tree

9 files changed

+129
-33
lines changed

9 files changed

+129
-33
lines changed

server/src/main/java/org/elasticsearch/search/SearchModule.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -417,9 +417,13 @@ private void registerAggregations(List<SearchPlugin> plugins) {
417417
registerAggregation(new AggregationSpec(SignificantTextAggregationBuilder.NAME, SignificantTextAggregationBuilder::new,
418418
SignificantTextAggregationBuilder::parse));
419419
registerAggregation(new AggregationSpec(RangeAggregationBuilder.NAME, RangeAggregationBuilder::new,
420-
RangeAggregationBuilder::parse).addResultReader(InternalRange::new));
420+
RangeAggregationBuilder::parse)
421+
.addResultReader(InternalRange::new)
422+
.setAggregatorRegistrar(RangeAggregationBuilder::registerAggregators));
421423
registerAggregation(new AggregationSpec(DateRangeAggregationBuilder.NAME, DateRangeAggregationBuilder::new,
422-
DateRangeAggregationBuilder::parse).addResultReader(InternalDateRange::new));
424+
DateRangeAggregationBuilder::parse)
425+
.addResultReader(InternalDateRange::new)
426+
.setAggregatorRegistrar(DateRangeAggregationBuilder::registerAggregators));
423427
registerAggregation(new AggregationSpec(IpRangeAggregationBuilder.NAME, IpRangeAggregationBuilder::new,
424428
IpRangeAggregationBuilder::parse).addResultReader(InternalBinaryRange::new));
425429
registerAggregation(new AggregationSpec(HistogramAggregationBuilder.NAME, HistogramAggregationBuilder::new,

server/src/main/java/org/elasticsearch/search/aggregations/bucket/range/AbstractRangeAggregatorFactory.java

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,21 @@
2020
package org.elasticsearch.search.aggregations.bucket.range;
2121

2222
import org.elasticsearch.index.query.QueryShardContext;
23+
import org.elasticsearch.search.DocValueFormat;
2324
import org.elasticsearch.search.aggregations.AggregationExecutionException;
2425
import org.elasticsearch.search.aggregations.Aggregator;
2526
import org.elasticsearch.search.aggregations.AggregatorFactories;
2627
import org.elasticsearch.search.aggregations.AggregatorFactory;
2728
import org.elasticsearch.search.aggregations.bucket.range.RangeAggregator.Range;
2829
import org.elasticsearch.search.aggregations.bucket.range.RangeAggregator.Unmapped;
2930
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
31+
import org.elasticsearch.search.aggregations.support.AggregatorSupplier;
32+
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
3033
import org.elasticsearch.search.aggregations.support.ValuesSource;
3134
import org.elasticsearch.search.aggregations.support.ValuesSource.Numeric;
3235
import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory;
3336
import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
37+
import org.elasticsearch.search.aggregations.support.ValuesSourceRegistry;
3438
import org.elasticsearch.search.internal.SearchContext;
3539

3640
import java.io.IOException;
@@ -42,20 +46,44 @@ public class AbstractRangeAggregatorFactory<R extends Range> extends ValuesSourc
4246
private final InternalRange.Factory<?, ?> rangeFactory;
4347
private final R[] ranges;
4448
private final boolean keyed;
49+
private final String aggregationTypeName;
4550

51+
public static void registerAggregators(ValuesSourceRegistry valuesSourceRegistry, String aggregationName) {
52+
valuesSourceRegistry.register(aggregationName,
53+
List.of(CoreValuesSourceType.NUMERIC, CoreValuesSourceType.DATE, CoreValuesSourceType.BOOLEAN),
54+
new RangeAggregatorSupplier() {
55+
@Override
56+
public Aggregator build(String name,
57+
AggregatorFactories factories,
58+
Numeric valuesSource,
59+
DocValueFormat format,
60+
InternalRange.Factory rangeFactory,
61+
Range[] ranges,
62+
boolean keyed,
63+
SearchContext context,
64+
Aggregator parent,
65+
List<PipelineAggregator> pipelineAggregators,
66+
Map<String, Object> metaData) throws IOException {
67+
return new RangeAggregator(name, factories, valuesSource, format, rangeFactory, ranges, keyed, context, parent,
68+
pipelineAggregators, metaData);
69+
}
70+
});
71+
}
4672
public AbstractRangeAggregatorFactory(String name,
47-
ValuesSourceConfig config,
48-
R[] ranges,
49-
boolean keyed,
50-
InternalRange.Factory<?, ?> rangeFactory,
51-
QueryShardContext queryShardContext,
52-
AggregatorFactory parent,
53-
AggregatorFactories.Builder subFactoriesBuilder,
54-
Map<String, Object> metaData) throws IOException {
73+
String aggregationTypeName,
74+
ValuesSourceConfig config,
75+
R[] ranges,
76+
boolean keyed,
77+
InternalRange.Factory<?, ?> rangeFactory,
78+
QueryShardContext queryShardContext,
79+
AggregatorFactory parent,
80+
AggregatorFactories.Builder subFactoriesBuilder,
81+
Map<String, Object> metaData) throws IOException {
5582
super(name, config, queryShardContext, parent, subFactoriesBuilder, metaData);
5683
this.ranges = ranges;
5784
this.keyed = keyed;
5885
this.rangeFactory = rangeFactory;
86+
this.aggregationTypeName = aggregationTypeName;
5987
}
6088

6189
@Override
@@ -73,13 +101,14 @@ protected Aggregator doCreateInternal(ValuesSource valuesSource,
73101
boolean collectsFromSingleBucket,
74102
List<PipelineAggregator> pipelineAggregators,
75103
Map<String, Object> metaData) throws IOException {
76-
if (valuesSource instanceof Numeric == false) {
77-
throw new AggregationExecutionException("ValuesSource type " + valuesSource.toString() + "is not supported for aggregation " +
78-
this.name());
104+
105+
AggregatorSupplier aggregatorSupplier = queryShardContext.getValuesSourceRegistry().getAggregator(config.valueSourceType(),
106+
aggregationTypeName);
107+
if (aggregatorSupplier instanceof RangeAggregatorSupplier == false) {
108+
throw new AggregationExecutionException("Registry miss-match - expected RangeAggregatorSupplier, found [" +
109+
aggregatorSupplier.getClass().toString() + "]");
79110
}
80-
return new RangeAggregator(name, factories, (Numeric) valuesSource, config.format(), rangeFactory, ranges, keyed, searchContext,
81-
parent, pipelineAggregators, metaData);
111+
return ((RangeAggregatorSupplier)aggregatorSupplier).build(name, factories, (Numeric) valuesSource, config.format(), rangeFactory,
112+
ranges, keyed, searchContext, parent, pipelineAggregators, metaData);
82113
}
83-
84-
85114
}

server/src/main/java/org/elasticsearch/search/aggregations/bucket/range/DateRangeAggregationBuilder.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
3131
import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
3232
import org.elasticsearch.search.aggregations.support.ValuesSourceParserHelper;
33+
import org.elasticsearch.search.aggregations.support.ValuesSourceRegistry;
3334
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
3435

3536
import java.io.IOException;
@@ -60,6 +61,10 @@ private static RangeAggregator.Range parseRange(XContentParser parser) throws IO
6061
return RangeAggregator.Range.fromXContent(parser);
6162
}
6263

64+
public static void registerAggregators(ValuesSourceRegistry valuesSourceRegistry) {
65+
AbstractRangeAggregatorFactory.registerAggregators(valuesSourceRegistry, NAME);
66+
}
67+
6368
public DateRangeAggregationBuilder(String name) {
6469
super(name, InternalDateRange.FACTORY);
6570
}

server/src/main/java/org/elasticsearch/search/aggregations/bucket/range/DateRangeAggregatorFactory.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,16 @@
3030
public class DateRangeAggregatorFactory extends AbstractRangeAggregatorFactory<RangeAggregator.Range> {
3131

3232
public DateRangeAggregatorFactory(String name,
33-
ValuesSourceConfig config,
34-
RangeAggregator.Range[] ranges,
35-
boolean keyed,
36-
InternalRange.Factory<?, ?> rangeFactory,
37-
QueryShardContext queryShardContext,
38-
AggregatorFactory parent,
39-
AggregatorFactories.Builder subFactoriesBuilder,
40-
Map<String, Object> metaData) throws IOException {
41-
super(name, config, ranges, keyed, rangeFactory, queryShardContext, parent, subFactoriesBuilder, metaData);
33+
ValuesSourceConfig config,
34+
RangeAggregator.Range[] ranges,
35+
boolean keyed,
36+
InternalRange.Factory<?, ?> rangeFactory,
37+
QueryShardContext queryShardContext,
38+
AggregatorFactory parent,
39+
AggregatorFactories.Builder subFactoriesBuilder,
40+
Map<String, Object> metaData) throws IOException {
41+
super(name, DateRangeAggregationBuilder.NAME, config, ranges, keyed, rangeFactory, queryShardContext, parent, subFactoriesBuilder,
42+
metaData);
4243
}
4344

4445
}

server/src/main/java/org/elasticsearch/search/aggregations/bucket/range/RangeAggregationBuilder.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.elasticsearch.search.aggregations.bucket.range.RangeAggregator.Range;
3131
import org.elasticsearch.search.aggregations.support.ValuesSourceConfig;
3232
import org.elasticsearch.search.aggregations.support.ValuesSourceParserHelper;
33+
import org.elasticsearch.search.aggregations.support.ValuesSourceRegistry;
3334

3435
import java.io.IOException;
3536
import java.util.Map;
@@ -58,6 +59,10 @@ private static Range parseRange(XContentParser parser) throws IOException {
5859
return Range.fromXContent(parser);
5960
}
6061

62+
public static void registerAggregators(ValuesSourceRegistry valuesSourceRegistry) {
63+
AbstractRangeAggregatorFactory.registerAggregators(valuesSourceRegistry, NAME);
64+
}
65+
6166
public RangeAggregationBuilder(String name) {
6267
super(name, InternalRange.FACTORY);
6368
}

server/src/main/java/org/elasticsearch/search/aggregations/bucket/range/RangeAggregatorFactory.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,17 @@
3131

3232
public class RangeAggregatorFactory extends AbstractRangeAggregatorFactory<RangeAggregator.Range> {
3333

34-
public RangeAggregatorFactory(String name, ValuesSourceConfig config, Range[] ranges, boolean keyed,
35-
Factory<?, ?> rangeFactory, QueryShardContext queryShardContext, AggregatorFactory parent,
36-
AggregatorFactories.Builder subFactoriesBuilder, Map<String, Object> metaData) throws IOException {
37-
super(name, config, ranges, keyed, rangeFactory, queryShardContext, parent, subFactoriesBuilder, metaData);
34+
public RangeAggregatorFactory(String name,
35+
ValuesSourceConfig config,
36+
Range[] ranges,
37+
boolean keyed,
38+
Factory<?, ?> rangeFactory,
39+
QueryShardContext queryShardContext,
40+
AggregatorFactory parent,
41+
AggregatorFactories.Builder subFactoriesBuilder,
42+
Map<String, Object> metaData) throws IOException {
43+
super(name, RangeAggregationBuilder.NAME, config, ranges, keyed, rangeFactory, queryShardContext, parent, subFactoriesBuilder,
44+
metaData);
3845
}
3946

4047
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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+
package org.elasticsearch.search.aggregations.bucket.range;
20+
21+
import org.elasticsearch.search.DocValueFormat;
22+
import org.elasticsearch.search.aggregations.Aggregator;
23+
import org.elasticsearch.search.aggregations.AggregatorFactories;
24+
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
25+
import org.elasticsearch.search.aggregations.support.AggregatorSupplier;
26+
import org.elasticsearch.search.aggregations.support.ValuesSource;
27+
import org.elasticsearch.search.internal.SearchContext;
28+
29+
import java.io.IOException;
30+
import java.util.List;
31+
import java.util.Map;
32+
33+
public interface RangeAggregatorSupplier extends AggregatorSupplier {
34+
Aggregator build(String name,
35+
AggregatorFactories factories,
36+
ValuesSource.Numeric valuesSource,
37+
DocValueFormat format,
38+
InternalRange.Factory rangeFactory,
39+
RangeAggregator.Range[] ranges,
40+
boolean keyed,
41+
SearchContext context,
42+
Aggregator parent,
43+
List<PipelineAggregator> pipelineAggregators,
44+
Map<String, Object> metaData) throws IOException;
45+
}

server/src/test/java/org/elasticsearch/search/aggregations/bucket/range/DateRangeAggregatorTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,8 @@ public void testKeywordField() {
224224
() -> testCase(aggregationBuilder, new MatchAllDocsQuery(), iw -> {
225225
iw.addDocument(singleton(new SortedSetDocValuesField("string", new BytesRef("foo"))));
226226
}, range -> fail("Should have thrown exception"), fieldType));
227-
// I believe this error is coming from improperly parsing the range, not the field.
228-
assertEquals("For input string: \"2015-11-13\"", e.getMessage());
227+
assertEquals("Field [not_a_number] of type [keyword(indexed,tokenized)] is not supported for aggregation [date_range]",
228+
e.getMessage());
229229
}
230230

231231
public void testBadMissingField() {

server/src/test/java/org/elasticsearch/search/aggregations/bucket/range/RangeAggregatorTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ public void testUnsupportedType() {
238238
() -> testCase(aggregationBuilder, new MatchAllDocsQuery(), iw -> {
239239
iw.addDocument(singleton(new SortedSetDocValuesField("string", new BytesRef("foo"))));
240240
}, range -> fail("Should have thrown exception"), fieldType));
241-
assertEquals(e.getMessage(), "Expected numeric type on field [not_a_number], but got [keyword]");
241+
assertEquals("Field [not_a_number] of type [keyword(indexed,tokenized)] is not supported for aggregation [range]", e.getMessage());
242242
}
243243

244244
public void testBadMissingField() {

0 commit comments

Comments
 (0)