Skip to content

Commit f491422

Browse files
authored
Ensure field types consistency on supporting text queries (#63487)
Some supported field types don't support term queries, and throw exception in their termQuery method. That exception is either an IllegalArgumentException or a QueryShardException. There is logic in MatchQuery that skips the field or not depending on the exception that is thrown. Also, such field types should hold a TextSearchInfo.NONE while that is not always the case. With this commit we make the following changes: - streamline using TextSearchInfo.NONE in all field types that don't support text queries - standardize the exception being thrown when a field type does not support term queries to be IllegalArgumentException. Note that this is not a breaking change as both exceptions previously returned translated to 400 status code. - Adapt the MatchQuery logic to skip fields that don't support term queries. There is no need to call termQuery passing an empty string and catch exceptions potentially thrown. We can rather check the TextSearchInfo which tells already whether the field supports text queries or not. - add a test method to MapperTestCase that verifies the consistency of a field type by verifying that it is not searchable whenever it uses TextSearchInfo.NONE, while it is otherwise. This is what triggered all of the above changes.
1 parent e8930a4 commit f491422

File tree

41 files changed

+165
-103
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+165
-103
lines changed

modules/mapper-extras/src/test/java/org/elasticsearch/index/mapper/RankFeatureFieldMapperTests.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@
3939
public class RankFeatureFieldMapperTests extends MapperTestCase {
4040

4141
@Override
42-
protected void writeFieldValue(XContentBuilder builder) throws IOException {
43-
builder.value(10);
42+
protected Object getSampleValueForDocument() {
43+
return 10;
4444
}
4545

4646
@Override
@@ -57,6 +57,12 @@ protected void assertExistsQuery(MappedFieldType fieldType, Query query, ParseCo
5757
assertNotNull(fields.getField("_feature"));
5858
}
5959

60+
@Override
61+
protected void assertSearchable(MappedFieldType fieldType) {
62+
//always searchable even if it uses TextSearchInfo.NONE
63+
assertTrue(fieldType.isSearchable());
64+
}
65+
6066
@Override
6167
protected Collection<? extends Plugin> getPlugins() {
6268
return List.of(new MapperExtrasPlugin());

modules/mapper-extras/src/test/java/org/elasticsearch/index/mapper/RankFeaturesFieldMapperTests.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,13 @@
3030
import java.util.Arrays;
3131
import java.util.Collection;
3232
import java.util.List;
33+
import java.util.Map;
3334

3435
public class RankFeaturesFieldMapperTests extends MapperTestCase {
3536

3637
@Override
37-
protected void writeFieldValue(XContentBuilder builder) throws IOException {
38-
builder.startObject().field("foo", 10).field("bar", 20).endObject();
38+
protected Object getSampleValueForDocument() {
39+
return Map.of("ten", 10, "twenty", 20);
3940
}
4041

4142
@Override
@@ -73,10 +74,17 @@ public void testDefaults() throws Exception {
7374
IndexableField[] fields = doc1.rootDoc().getFields("field");
7475
assertEquals(2, fields.length);
7576
assertThat(fields[0], Matchers.instanceOf(FeatureField.class));
76-
FeatureField featureField1 = (FeatureField) fields[0];
77-
assertThat(featureField1.stringValue(), Matchers.equalTo("foo"));
78-
FeatureField featureField2 = (FeatureField) fields[1];
79-
assertThat(featureField2.stringValue(), Matchers.equalTo("bar"));
77+
FeatureField featureField1 = null;
78+
FeatureField featureField2 = null;
79+
for (IndexableField field : fields) {
80+
if (field.stringValue().equals("ten")) {
81+
featureField1 = (FeatureField)field;
82+
} else if (field.stringValue().equals("twenty")) {
83+
featureField2 = (FeatureField)field;
84+
} else {
85+
throw new UnsupportedOperationException();
86+
}
87+
}
8088

8189
int freq1 = RankFeatureFieldMapperTests.getFrequency(featureField1.tokenStream(null, null));
8290
int freq2 = RankFeatureFieldMapperTests.getFrequency(featureField2.tokenStream(null, null));

modules/mapper-extras/src/test/java/org/elasticsearch/index/mapper/ScaledFloatFieldMapperTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ protected Collection<? extends Plugin> getPlugins() {
4444
}
4545

4646
@Override
47-
protected void writeFieldValue(XContentBuilder builder) throws IOException {
48-
builder.value(123);
47+
protected Object getSampleValueForDocument() {
48+
return 123;
4949
}
5050

5151
@Override

modules/mapper-extras/src/test/java/org/elasticsearch/index/mapper/SearchAsYouTypeFieldMapperTests.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,9 @@ protected void registerParameters(ParameterChecker checker) throws IOException {
122122

123123
}
124124

125-
protected void writeFieldValue(XContentBuilder builder) throws IOException {
126-
builder.value("new york city");
125+
@Override
126+
protected Object getSampleValueForDocument() {
127+
return "new york city";
127128
}
128129

129130
@Override

modules/mapper-extras/src/test/java/org/elasticsearch/index/mapper/TokenCountFieldMapperTests.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,13 @@ protected void minimalMapping(XContentBuilder b) throws IOException {
5757
}
5858

5959
@Override
60-
protected void writeFieldValue(XContentBuilder builder) throws IOException {
61-
builder.value("some words");
60+
protected Object getSampleValueForDocument() {
61+
return "some words";
62+
}
63+
64+
@Override
65+
protected Object getSampleValueForQuery() {
66+
return 1;
6267
}
6368

6469
@Override

plugins/analysis-icu/src/test/java/org/elasticsearch/index/mapper/ICUCollationKeywordFieldMapperTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ protected void minimalMapping(XContentBuilder b) throws IOException {
6969
}
7070

7171
@Override
72-
protected void writeFieldValue(XContentBuilder builder) throws IOException {
73-
builder.value(1234);
72+
protected Object getSampleValueForDocument() {
73+
return 1234;
7474
}
7575

7676
public void testDefaults() throws Exception {

plugins/mapper-annotated-text/src/internalClusterTest/java/org/elasticsearch/index/mapper/annotatedtext/AnnotatedTextFieldMapperTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ protected void minimalMapping(XContentBuilder b) throws IOException {
8080
}
8181

8282
@Override
83-
protected void writeFieldValue(XContentBuilder builder) throws IOException {
84-
builder.value("some text");
83+
protected Object getSampleValueForDocument() {
84+
return "some text";
8585
}
8686

8787
@Override

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
import org.elasticsearch.index.mapper.TextSearchInfo;
3939
import org.elasticsearch.index.mapper.ValueFetcher;
4040
import org.elasticsearch.index.query.QueryShardContext;
41-
import org.elasticsearch.index.query.QueryShardException;
4241
import org.elasticsearch.search.lookup.SearchLookup;
4342

4443
import java.io.IOException;
@@ -91,7 +90,7 @@ public Murmur3FieldMapper build(BuilderContext context) {
9190
// this only exists so a check can be done to match the field type to using murmur3 hashing...
9291
public static class Murmur3FieldType extends MappedFieldType {
9392
private Murmur3FieldType(String name, boolean isStored, Map<String, String> meta) {
94-
super(name, false, isStored, true, TextSearchInfo.SIMPLE_MATCH_ONLY, meta);
93+
super(name, false, isStored, true, TextSearchInfo.NONE, meta);
9594
}
9695

9796
@Override
@@ -112,7 +111,7 @@ public ValueFetcher valueFetcher(MapperService mapperService, SearchLookup searc
112111

113112
@Override
114113
public Query termQuery(Object value, QueryShardContext context) {
115-
throw new QueryShardException(context, "Murmur3 fields are not searchable: [" + name() + "]");
114+
throw new IllegalArgumentException("Murmur3 fields are not searchable: [" + name() + "]");
116115
}
117116
}
118117

plugins/mapper-murmur3/src/test/java/org/elasticsearch/index/mapper/murmur3/Murmur3FieldMapperTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@
3737
public class Murmur3FieldMapperTests extends MapperTestCase {
3838

3939
@Override
40-
protected void writeFieldValue(XContentBuilder builder) throws IOException {
41-
builder.value("value");
40+
protected Object getSampleValueForDocument() {
41+
return "value";
4242
}
4343

4444
@Override

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

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
import org.elasticsearch.common.xcontent.support.MapXContentParser;
3434
import org.elasticsearch.common.xcontent.support.XContentMapValues;
3535
import org.elasticsearch.index.query.QueryShardContext;
36-
import org.elasticsearch.index.query.QueryShardException;
3736
import org.elasticsearch.search.lookup.SearchLookup;
3837

3938
import java.io.IOException;
@@ -224,7 +223,7 @@ public abstract static class AbstractGeometryFieldType<Parsed, Processed> extend
224223

225224
protected AbstractGeometryFieldType(String name, boolean indexed, boolean stored, boolean hasDocValues,
226225
boolean parsesArrayValue, Map<String, String> meta) {
227-
super(name, indexed, stored, hasDocValues, TextSearchInfo.SIMPLE_MATCH_ONLY, meta);
226+
super(name, indexed, stored, hasDocValues, TextSearchInfo.NONE, meta);
228227
this.parsesArrayValue = parsesArrayValue;
229228
}
230229

@@ -245,14 +244,13 @@ protected Parser<Parsed> geometryParser() {
245244
}
246245

247246
@Override
248-
public Query termQuery(Object value, QueryShardContext context) {
249-
throw new QueryShardException(context,
250-
"Geometry fields do not support exact searching, use dedicated geometry queries instead: ["
247+
public final Query termQuery(Object value, QueryShardContext context) {
248+
throw new IllegalArgumentException("Geometry fields do not support exact searching, use dedicated geometry queries instead: ["
251249
+ name() + "]");
252250
}
253251

254252
@Override
255-
public ValueFetcher valueFetcher(MapperService mapperService, SearchLookup searchLookup, String format) {
253+
public final ValueFetcher valueFetcher(MapperService mapperService, SearchLookup searchLookup, String format) {
256254
String geoFormat = format != null ? format : GeoJsonGeometryFormat.NAME;
257255

258256
Function<Object, Object> valueParser = value -> geometryParser.parseAndFormatObject(value, geoFormat);

0 commit comments

Comments
 (0)