Skip to content

Commit 50462bb

Browse files
committed
Aggregations Refactor: Refactor Geo Centroid Aggregation
1 parent c5a6886 commit 50462bb

File tree

4 files changed

+152
-30
lines changed

4 files changed

+152
-30
lines changed

core/src/main/java/org/elasticsearch/search/aggregations/metrics/geocentroid/GeoCentroidAggregator.java

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,24 @@
2222
import org.apache.lucene.index.LeafReaderContext;
2323
import org.apache.lucene.util.GeoUtils;
2424
import org.elasticsearch.common.geo.GeoPoint;
25+
import org.elasticsearch.common.io.stream.StreamInput;
26+
import org.elasticsearch.common.io.stream.StreamOutput;
2527
import org.elasticsearch.common.lease.Releasables;
2628
import org.elasticsearch.common.util.BigArrays;
2729
import org.elasticsearch.common.util.LongArray;
30+
import org.elasticsearch.common.xcontent.XContentBuilder;
2831
import org.elasticsearch.index.fielddata.MultiGeoPointValues;
2932
import org.elasticsearch.search.aggregations.Aggregator;
3033
import org.elasticsearch.search.aggregations.InternalAggregation;
3134
import org.elasticsearch.search.aggregations.LeafBucketCollector;
3235
import org.elasticsearch.search.aggregations.LeafBucketCollectorBase;
3336
import org.elasticsearch.search.aggregations.metrics.MetricsAggregator;
34-
import org.elasticsearch.search.aggregations.metrics.geobounds.InternalGeoBounds;
3537
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
3638
import org.elasticsearch.search.aggregations.support.AggregationContext;
39+
import org.elasticsearch.search.aggregations.support.ValueType;
3740
import org.elasticsearch.search.aggregations.support.ValuesSource;
3841
import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory;
39-
import org.elasticsearch.search.aggregations.support.ValuesSourceParser;
42+
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
4043

4144
import java.io.IOException;
4245
import java.util.List;
@@ -123,8 +126,9 @@ public void doClose() {
123126
}
124127

125128
public static class Factory extends ValuesSourceAggregatorFactory.LeafOnly<ValuesSource.GeoPoint> {
126-
protected Factory(String name, ValuesSourceParser.Input<ValuesSource.GeoPoint> config) {
127-
super(name, InternalGeoBounds.TYPE, config);
129+
130+
public Factory(String name) {
131+
super(name, InternalGeoCentroid.TYPE, ValuesSourceType.GEOPOINT, ValueType.GEOPOINT);
128132
}
129133

130134
@Override
@@ -139,5 +143,31 @@ protected Aggregator doCreateInternal(ValuesSource.GeoPoint valuesSource, Aggreg
139143
throws IOException {
140144
return new GeoCentroidAggregator(name, aggregationContext, parent, valuesSource, pipelineAggregators, metaData);
141145
}
146+
147+
@Override
148+
protected ValuesSourceAggregatorFactory<ValuesSource.GeoPoint> innerReadFrom(String name, ValuesSourceType valuesSourceType,
149+
ValueType targetValueType, StreamInput in) throws IOException {
150+
return new Factory(name);
151+
}
152+
153+
@Override
154+
protected void innerWriteTo(StreamOutput out) {
155+
// Do nothing, no extra state to write to stream
156+
}
157+
158+
@Override
159+
public XContentBuilder doXContentBody(XContentBuilder builder, Params params) throws IOException {
160+
return builder;
161+
}
162+
163+
@Override
164+
protected int innerHashCode() {
165+
return 0;
166+
}
167+
168+
@Override
169+
protected boolean innerEquals(Object obj) {
170+
return true;
171+
}
142172
}
143173
}

core/src/main/java/org/elasticsearch/search/aggregations/metrics/geocentroid/GeoCentroidParser.java

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,51 +19,48 @@
1919

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

22+
import org.elasticsearch.common.ParseField;
23+
import org.elasticsearch.common.ParseFieldMatcher;
2224
import org.elasticsearch.common.xcontent.XContentParser;
23-
import org.elasticsearch.search.SearchParseException;
24-
import org.elasticsearch.search.aggregations.Aggregator;
25+
import org.elasticsearch.common.xcontent.XContentParser.Token;
2526
import org.elasticsearch.search.aggregations.AggregatorFactory;
27+
import org.elasticsearch.search.aggregations.support.AbstractValuesSourceParser.GeoPointValuesSourceParser;
2628
import org.elasticsearch.search.aggregations.support.ValueType;
27-
import org.elasticsearch.search.aggregations.support.ValuesSource;
28-
import org.elasticsearch.search.aggregations.support.ValuesSourceParser;
29-
import org.elasticsearch.search.internal.SearchContext;
29+
import org.elasticsearch.search.aggregations.support.ValuesSource.GeoPoint;
30+
import org.elasticsearch.search.aggregations.support.ValuesSourceAggregatorFactory;
31+
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
3032

3133
import java.io.IOException;
34+
import java.util.Map;
3235

3336
/**
3437
* Parser class for {@link org.elasticsearch.search.aggregations.metrics.geocentroid.GeoCentroidAggregator}
3538
*/
36-
public class GeoCentroidParser implements Aggregator.Parser {
39+
public class GeoCentroidParser extends GeoPointValuesSourceParser {
40+
41+
public GeoCentroidParser() {
42+
super(true, false);
43+
}
3744

3845
@Override
3946
public String type() {
4047
return InternalGeoCentroid.TYPE.name();
4148
}
4249

4350
@Override
44-
public AggregatorFactory parse(String aggregationName, XContentParser parser, SearchContext context) throws IOException {
45-
ValuesSourceParser<ValuesSource.GeoPoint> vsParser = ValuesSourceParser.geoPoint(aggregationName, InternalGeoCentroid.TYPE, context)
46-
.targetValueType(ValueType.GEOPOINT)
47-
.formattable(true)
48-
.build();
49-
XContentParser.Token token;
50-
String currentFieldName = null;
51-
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
52-
if (token == XContentParser.Token.FIELD_NAME) {
53-
currentFieldName = parser.currentName();
54-
} else if (vsParser.token(currentFieldName, token, parser)) {
55-
continue;
56-
} else {
57-
throw new SearchParseException(context, "Unknown key for a " + token + " in aggregation [" + aggregationName + "]: ["
58-
+ currentFieldName + "].", parser.getTokenLocation());
59-
}
60-
}
61-
return new GeoCentroidAggregator.Factory(aggregationName, vsParser.input());
51+
protected boolean token(String aggregationName, String currentFieldName, Token token, XContentParser parser,
52+
ParseFieldMatcher parseFieldMatcher, Map<ParseField, Object> otherOptions) throws IOException {
53+
return false;
54+
}
55+
56+
@Override
57+
protected ValuesSourceAggregatorFactory<GeoPoint> createFactory(String aggregationName, ValuesSourceType valuesSourceType,
58+
ValueType targetValueType, Map<ParseField, Object> otherOptions) {
59+
return new GeoCentroidAggregator.Factory(aggregationName);
6260
}
6361

64-
// NORELEASE implement this method when refactoring this aggregation
6562
@Override
6663
public AggregatorFactory[] getFactoryPrototypes() {
67-
return null;
64+
return new AggregatorFactory[] { new GeoCentroidAggregator.Factory(null) };
6865
}
6966
}

core/src/main/java/org/elasticsearch/search/aggregations/support/AbstractValuesSourceParser.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,52 @@ public final AggregatorFactory parse(String aggregationName, XContentParser pars
155155
return factory;
156156
}
157157

158+
/**
159+
* Creates a {@link ValuesSourceAggregatorFactory} from the information
160+
* gathered by the subclass. Options parsed in
161+
* {@link AbstractValuesSourceParser} itself will be added to the factory
162+
* after it has been returned by this method.
163+
*
164+
* @param aggregationName
165+
* the name of the aggregation
166+
* @param valuesSourceType
167+
* the type of the {@link ValuesSource}
168+
* @param targetValueType
169+
* the target type of the final value output by the aggregation
170+
* @param otherOptions
171+
* a {@link Map} containing the extra options parsed by the
172+
* {@link #token(String, String, org.elasticsearch.common.xcontent.XContentParser.Token, XContentParser, ParseFieldMatcher, Map)}
173+
* method
174+
* @return the created factory
175+
*/
158176
protected abstract ValuesSourceAggregatorFactory<VS> createFactory(String aggregationName, ValuesSourceType valuesSourceType,
159177
ValueType targetValueType, Map<ParseField, Object> otherOptions);
160178

179+
/**
180+
* Allows subclasses of {@link AbstractValuesSourceParser} to parse extra
181+
* parameters and store them in a {@link Map} which will later be passed to
182+
* {@link #createFactory(String, ValuesSourceType, ValueType, Map)}.
183+
*
184+
* @param aggregationName
185+
* the name of the aggregation
186+
* @param currentFieldName
187+
* the name of the current field being parsed
188+
* @param token
189+
* the current token for the parser
190+
* @param parser
191+
* the parser
192+
* @param parseFieldMatcher
193+
* the {@link ParseFieldMatcher} to use to match field names
194+
* @param otherOptions
195+
* a {@link Map} of options to be populated by successive calls
196+
* to this method which will then be passed to the
197+
* {@link #createFactory(String, ValuesSourceType, ValueType, Map)}
198+
* method
199+
* @return <code>true</code> if the current token was correctly parsed,
200+
* <code>false</code> otherwise
201+
* @throws IOException
202+
* if an error occurs whilst parsing
203+
*/
161204
protected abstract boolean token(String aggregationName, String currentFieldName, XContentParser.Token token, XContentParser parser,
162205
ParseFieldMatcher parseFieldMatcher, Map<ParseField, Object> otherOptions) throws IOException;
163206
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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.metrics;
21+
22+
import org.elasticsearch.script.Script;
23+
import org.elasticsearch.search.aggregations.BaseAggregationTestCase;
24+
import org.elasticsearch.search.aggregations.metrics.geocentroid.GeoCentroidAggregator;
25+
import org.elasticsearch.search.aggregations.metrics.geocentroid.GeoCentroidAggregator.Factory;
26+
27+
public class GeoCentroidTests extends BaseAggregationTestCase<GeoCentroidAggregator.Factory> {
28+
29+
@Override
30+
protected Factory createTestAggregatorFactory() {
31+
Factory factory = new Factory(randomAsciiOfLengthBetween(1, 20));
32+
String field = randomNumericField();
33+
int randomFieldBranch = randomInt(3);
34+
switch (randomFieldBranch) {
35+
case 0:
36+
factory.field(field);
37+
break;
38+
case 1:
39+
factory.field(field);
40+
factory.script(new Script("_value + 1"));
41+
break;
42+
case 2:
43+
factory.script(new Script("doc[" + field + "] + 1"));
44+
break;
45+
}
46+
if (randomBoolean()) {
47+
factory.missing("0,0");
48+
}
49+
return factory;
50+
}
51+
52+
}

0 commit comments

Comments
 (0)