Skip to content

Commit f05b831

Browse files
Comprehensively test supported/unsupported field type:agg combinations (#52493)
This adds a test to AggregatorTestCase that allows us to programmatically verify that an aggregator supports or does not support a particular field type. It fetches the list of registered field type parsers, creates a MappedFieldType from the parser and then attempts to run a basic agg against the field. A supplied list of supported VSTypes are then compared against the output (success or exception) and suceeds or fails the test accordingly. Co-Authored-By: Mark Tozzi <[email protected]> * Skip fields that are not aggregatable
1 parent 303aaf4 commit f05b831

File tree

28 files changed

+427
-52
lines changed

28 files changed

+427
-52
lines changed

modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/ScaledFloatFieldMapper.java

+7
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@
6262
import org.elasticsearch.search.MultiValueMode;
6363
import org.elasticsearch.search.sort.BucketedSort;
6464
import org.elasticsearch.search.sort.SortOrder;
65+
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
66+
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
6567

6668
import java.io.IOException;
6769
import java.math.BigDecimal;
@@ -295,6 +297,11 @@ public IndexFieldData<?> build(IndexSettings indexSettings, MappedFieldType fiel
295297
};
296298
}
297299

300+
@Override
301+
public ValuesSourceType getValuesSourceType() {
302+
return CoreValuesSourceType.NUMERIC;
303+
}
304+
298305
@Override
299306
public Object valueForDisplay(Object value) {
300307
if (value == null) {

modules/parent-join/src/main/java/org/elasticsearch/join/mapper/MetaJoinFieldMapper.java

+7
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import org.elasticsearch.index.mapper.ParseContext;
3232
import org.elasticsearch.index.mapper.StringFieldType;
3333
import org.elasticsearch.index.query.QueryShardContext;
34+
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
35+
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
3436

3537
import java.io.IOException;
3638
import java.util.List;
@@ -95,6 +97,11 @@ public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) {
9597
return new DocValuesIndexFieldData.Builder();
9698
}
9799

100+
@Override
101+
public ValuesSourceType getValuesSourceType() {
102+
return CoreValuesSourceType.BYTES;
103+
}
104+
98105
@Override
99106
public Object valueForDisplay(Object value) {
100107
if (value == null) {

modules/parent-join/src/main/java/org/elasticsearch/join/mapper/ParentIdFieldMapper.java

+7
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
import org.elasticsearch.index.mapper.ParseContext;
4242
import org.elasticsearch.index.mapper.StringFieldType;
4343
import org.elasticsearch.index.query.QueryShardContext;
44+
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
45+
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
4446

4547
import java.io.IOException;
4648
import java.util.Collection;
@@ -118,6 +120,11 @@ public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) {
118120
return new DocValuesIndexFieldData.Builder();
119121
}
120122

123+
@Override
124+
public ValuesSourceType getValuesSourceType() {
125+
return CoreValuesSourceType.BYTES;
126+
}
127+
121128
@Override
122129
public Object valueForDisplay(Object value) {
123130
if (value == null) {

modules/parent-join/src/main/java/org/elasticsearch/join/mapper/ParentJoinFieldMapper.java

+7
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@
4343
import org.elasticsearch.index.mapper.ParseContext;
4444
import org.elasticsearch.index.mapper.StringFieldType;
4545
import org.elasticsearch.index.query.QueryShardContext;
46+
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
47+
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
4648

4749
import java.io.IOException;
4850
import java.util.ArrayList;
@@ -227,6 +229,11 @@ public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) {
227229
return new DocValuesIndexFieldData.Builder();
228230
}
229231

232+
@Override
233+
public ValuesSourceType getValuesSourceType() {
234+
return CoreValuesSourceType.BYTES;
235+
}
236+
230237
@Override
231238
public Object valueForDisplay(Object value) {
232239
if (value == null) {

plugins/analysis-icu/src/main/java/org/elasticsearch/index/mapper/ICUCollationKeywordFieldMapper.java

+7
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646
import org.elasticsearch.index.fielddata.plain.DocValuesIndexFieldData;
4747
import org.elasticsearch.index.query.QueryShardContext;
4848
import org.elasticsearch.search.DocValueFormat;
49+
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
50+
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
4951

5052
import java.io.IOException;
5153
import java.time.ZoneId;
@@ -139,6 +141,11 @@ public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) {
139141
return new DocValuesIndexFieldData.Builder();
140142
}
141143

144+
@Override
145+
public ValuesSourceType getValuesSourceType() {
146+
return CoreValuesSourceType.BYTES;
147+
}
148+
142149
@Override
143150
protected BytesRef indexedValueForSearch(Object value) {
144151
if (value == null) {

plugins/mapper-murmur3/src/main/java/org/elasticsearch/index/mapper/murmur3/Murmur3FieldMapper.java

+7
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
import org.elasticsearch.index.mapper.TypeParsers;
4040
import org.elasticsearch.index.query.QueryShardContext;
4141
import org.elasticsearch.index.query.QueryShardException;
42+
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
43+
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
4244

4345
import java.io.IOException;
4446
import java.util.List;
@@ -124,6 +126,11 @@ public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) {
124126
return new DocValuesIndexFieldData.Builder().numericType(NumericType.LONG);
125127
}
126128

129+
@Override
130+
public ValuesSourceType getValuesSourceType() {
131+
return CoreValuesSourceType.NUMERIC;
132+
}
133+
127134
@Override
128135
public Query existsQuery(QueryShardContext context) {
129136
return new DocValuesFieldExistsQuery(name());

server/src/main/java/org/elasticsearch/index/mapper/BinaryFieldMapper.java

+7
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
import org.elasticsearch.index.query.QueryShardContext;
4141
import org.elasticsearch.index.query.QueryShardException;
4242
import org.elasticsearch.search.DocValueFormat;
43+
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
44+
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
4345

4446
import java.io.IOException;
4547
import java.time.ZoneId;
@@ -136,6 +138,11 @@ public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) {
136138
return new BytesBinaryDVIndexFieldData.Builder();
137139
}
138140

141+
@Override
142+
public ValuesSourceType getValuesSourceType() {
143+
return CoreValuesSourceType.BYTES;
144+
}
145+
139146
@Override
140147
public Query existsQuery(QueryShardContext context) {
141148
if (hasDocValues()) {

server/src/main/java/org/elasticsearch/index/mapper/BooleanFieldMapper.java

+7
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
import org.elasticsearch.index.fielddata.plain.DocValuesIndexFieldData;
4141
import org.elasticsearch.index.query.QueryShardContext;
4242
import org.elasticsearch.search.DocValueFormat;
43+
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
44+
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
4345

4446
import java.io.IOException;
4547
import java.time.ZoneId;
@@ -189,6 +191,11 @@ public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) {
189191
return new DocValuesIndexFieldData.Builder().numericType(NumericType.BOOLEAN);
190192
}
191193

194+
@Override
195+
public ValuesSourceType getValuesSourceType() {
196+
return CoreValuesSourceType.NUMERIC;
197+
}
198+
192199
@Override
193200
public DocValueFormat docValueFormat(@Nullable String format, ZoneId timeZone) {
194201
if (format != null) {

server/src/main/java/org/elasticsearch/index/mapper/DateFieldMapper.java

+9-1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@
5252
import org.elasticsearch.index.query.QueryRewriteContext;
5353
import org.elasticsearch.index.query.QueryShardContext;
5454
import org.elasticsearch.search.DocValueFormat;
55+
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
56+
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
5557

5658
import java.io.IOException;
5759
import java.time.DateTimeException;
@@ -71,6 +73,7 @@
7173
public final class DateFieldMapper extends FieldMapper {
7274

7375
public static final String CONTENT_TYPE = "date";
76+
public static final String DATE_NANOS_CONTENT_TYPE = "date_nanos";
7477
public static final DateFormatter DEFAULT_DATE_TIME_FORMATTER = DateFormatter.forPattern("strict_date_optional_time||epoch_millis");
7578

7679
public static class Defaults {
@@ -94,7 +97,7 @@ public Instant clampToValidRange(Instant instant) {
9497
return instant;
9598
}
9699
},
97-
NANOSECONDS("date_nanos", NumericType.DATE_NANOSECONDS) {
100+
NANOSECONDS(DATE_NANOS_CONTENT_TYPE, NumericType.DATE_NANOSECONDS) {
98101
@Override
99102
public long convert(Instant instant) {
100103
return toLong(instant);
@@ -505,6 +508,11 @@ public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) {
505508
return new DocValuesIndexFieldData.Builder().numericType(resolution.numericType());
506509
}
507510

511+
@Override
512+
public ValuesSourceType getValuesSourceType() {
513+
return CoreValuesSourceType.NUMERIC;
514+
}
515+
508516
@Override
509517
public Object valueForDisplay(Object value) {
510518
Long val = (Long) value;

server/src/main/java/org/elasticsearch/index/mapper/GeoPointFieldMapper.java

+7
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
import org.elasticsearch.index.fielddata.plain.AbstractLatLonPointDVIndexFieldData;
4141
import org.elasticsearch.index.query.QueryShardContext;
4242
import org.elasticsearch.index.query.QueryShardException;
43+
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
44+
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
4345

4446
import java.io.IOException;
4547
import java.util.ArrayList;
@@ -235,6 +237,11 @@ public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) {
235237
return new AbstractLatLonPointDVIndexFieldData.Builder();
236238
}
237239

240+
@Override
241+
public ValuesSourceType getValuesSourceType() {
242+
return CoreValuesSourceType.GEOPOINT;
243+
}
244+
238245
@Override
239246
public Query existsQuery(QueryShardContext context) {
240247
if (hasDocValues()) {

server/src/main/java/org/elasticsearch/index/mapper/IdFieldMapper.java

+8
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
import org.elasticsearch.search.MultiValueMode;
5151
import org.elasticsearch.search.sort.BucketedSort;
5252
import org.elasticsearch.search.sort.SortOrder;
53+
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
54+
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
5355

5456
import java.io.IOException;
5557
import java.util.Arrays;
@@ -157,6 +159,12 @@ public Query termsQuery(List<?> values, QueryShardContext context) {
157159
return new TermInSetQuery(name(), bytesRefs);
158160
}
159161

162+
@Override
163+
public ValuesSourceType getValuesSourceType() {
164+
// TODO: should this even exist? Is aggregating on the ID field valid?
165+
return CoreValuesSourceType.BYTES;
166+
}
167+
160168
@Override
161169
public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) {
162170
if (indexOptions() == IndexOptions.NONE) {

server/src/main/java/org/elasticsearch/index/mapper/IndexFieldMapper.java

+8
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
import org.elasticsearch.index.fielddata.IndexFieldData;
3434
import org.elasticsearch.index.fielddata.plain.ConstantIndexFieldData;
3535
import org.elasticsearch.index.query.QueryShardContext;
36+
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
37+
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
3638

3739
import java.io.IOException;
3840
import java.util.List;
@@ -189,6 +191,12 @@ public Query wildcardQuery(String value,
189191
public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) {
190192
return new ConstantIndexFieldData.Builder(mapperService -> fullyQualifiedIndexName);
191193
}
194+
195+
@Override
196+
public ValuesSourceType getValuesSourceType() {
197+
// TODO: Should Index fields be aggregatable? What even is an IndexField?
198+
return CoreValuesSourceType.BYTES;
199+
}
192200
}
193201

194202
private IndexFieldMapper(Settings indexSettings, MappedFieldType existing) {

server/src/main/java/org/elasticsearch/index/mapper/IpFieldMapper.java

+7
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
import org.elasticsearch.index.fielddata.plain.DocValuesIndexFieldData;
4545
import org.elasticsearch.index.query.QueryShardContext;
4646
import org.elasticsearch.search.DocValueFormat;
47+
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
48+
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
4749

4850
import java.io.IOException;
4951
import java.net.InetAddress;
@@ -294,6 +296,11 @@ public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) {
294296
return new DocValuesIndexFieldData.Builder().scriptFunction(IpScriptDocValues::new);
295297
}
296298

299+
@Override
300+
public ValuesSourceType getValuesSourceType() {
301+
return CoreValuesSourceType.BYTES;
302+
}
303+
297304
@Override
298305
public Object valueForDisplay(Object value) {
299306
if (value == null) {

server/src/main/java/org/elasticsearch/index/mapper/KeywordFieldMapper.java

+7
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@
4343
import org.elasticsearch.index.fielddata.IndexFieldData;
4444
import org.elasticsearch.index.fielddata.plain.DocValuesIndexFieldData;
4545
import org.elasticsearch.index.query.QueryShardContext;
46+
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
47+
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
4648

4749
import java.io.IOException;
4850
import java.util.Iterator;
@@ -271,6 +273,11 @@ public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) {
271273
return new DocValuesIndexFieldData.Builder();
272274
}
273275

276+
@Override
277+
public ValuesSourceType getValuesSourceType() {
278+
return CoreValuesSourceType.BYTES;
279+
}
280+
274281
@Override
275282
public Object valueForDisplay(Object value) {
276283
if (value == null) {

server/src/main/java/org/elasticsearch/index/mapper/MappedFieldType.java

+11
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import org.elasticsearch.index.query.QueryShardException;
5151
import org.elasticsearch.index.similarity.SimilarityProvider;
5252
import org.elasticsearch.search.DocValueFormat;
53+
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
5354

5455
import java.io.IOException;
5556
import java.time.ZoneId;
@@ -117,6 +118,16 @@ public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) {
117118
throw new IllegalArgumentException("Fielddata is not supported on field [" + name() + "] of type [" + typeName() + "]");
118119
}
119120

121+
/**
122+
* Returns the {@link ValuesSourceType} which supports this field type. This is tightly coupled to field data and aggregations support,
123+
* so any implementation that returns a value from {@link MappedFieldType#fielddataBuilder} should also return a value from here.
124+
*
125+
* @return The appropriate {@link ValuesSourceType} for this field type.
126+
*/
127+
public ValuesSourceType getValuesSourceType() {
128+
throw new IllegalArgumentException("Aggregations are not supported on field [" + name() + "] of type [" + typeName() + "]");
129+
}
130+
120131
@Override
121132
public boolean equals(Object o) {
122133
if (!super.equals(o)) return false;

server/src/main/java/org/elasticsearch/index/mapper/NumberFieldMapper.java

+7
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@
5555
import org.elasticsearch.index.fielddata.plain.DocValuesIndexFieldData;
5656
import org.elasticsearch.index.query.QueryShardContext;
5757
import org.elasticsearch.search.DocValueFormat;
58+
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
59+
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
5860

5961
import java.io.IOException;
6062
import java.time.ZoneId;
@@ -958,6 +960,11 @@ public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) {
958960
return new DocValuesIndexFieldData.Builder().numericType(type.numericType());
959961
}
960962

963+
@Override
964+
public ValuesSourceType getValuesSourceType() {
965+
return CoreValuesSourceType.NUMERIC;
966+
}
967+
961968
@Override
962969
public Object valueForDisplay(Object value) {
963970
if (value == null) {

server/src/main/java/org/elasticsearch/index/mapper/RangeFieldMapper.java

+7-8
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
import org.elasticsearch.index.fielddata.plain.DocValuesIndexFieldData;
4646
import org.elasticsearch.index.query.QueryShardContext;
4747
import org.elasticsearch.search.DocValueFormat;
48+
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
49+
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
4850

4951
import java.io.IOException;
5052
import java.net.InetAddress;
@@ -92,14 +94,6 @@ public RangeFieldType fieldType() {
9294
return (RangeFieldType)fieldType;
9395
}
9496

95-
@Override
96-
public Builder docValues(boolean docValues) {
97-
if (docValues) {
98-
throw new IllegalArgumentException("field [" + name + "] does not currently support " + TypeParsers.DOC_VALUES);
99-
}
100-
return super.docValues(docValues);
101-
}
102-
10397
public Builder coerce(boolean coerce) {
10498
this.coerce = coerce;
10599
return builder;
@@ -242,6 +236,11 @@ public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) {
242236
return new DocValuesIndexFieldData.Builder().setRangeType(rangeType);
243237
}
244238

239+
@Override
240+
public ValuesSourceType getValuesSourceType() {
241+
return CoreValuesSourceType.RANGE;
242+
}
243+
245244
@Override
246245
public String typeName() {
247246
return rangeType.name;

0 commit comments

Comments
 (0)