Skip to content

Commit 9454c6a

Browse files
committed
When creating wildcard queries, use MatchNoDocsQuery when the field type doesn't exist. (#34093)
1 parent 161f480 commit 9454c6a

File tree

7 files changed

+36
-38
lines changed

7 files changed

+36
-38
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.apache.lucene.search.TermQuery;
3636
import org.apache.lucene.util.BytesRef;
3737
import org.elasticsearch.Version;
38+
import org.elasticsearch.common.Nullable;
3839
import org.elasticsearch.common.io.stream.StreamOutput;
3940
import org.elasticsearch.common.lucene.Lucene;
4041
import org.elasticsearch.common.settings.Settings;
@@ -177,7 +178,9 @@ public Query prefixQuery(String value, MultiTermQuery.RewriteMethod method, Quer
177178
}
178179

179180
@Override
180-
public Query wildcardQuery(String value, QueryShardContext context) {
181+
public Query wildcardQuery(String value,
182+
@Nullable MultiTermQuery.RewriteMethod method,
183+
QueryShardContext context) {
181184
throw new UnsupportedOperationException("[wildcard] queries are not supported on [" + CONTENT_TYPE + "] fields.");
182185
}
183186

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ public void testWildcardQuery() {
126126
ft.setName("field");
127127
ft.setIndexOptions(IndexOptions.DOCS);
128128
expectThrows(UnsupportedOperationException.class,
129-
() -> ft.wildcardQuery("foo*", null));
129+
() -> ft.wildcardQuery("foo*", null, null));
130130
}
131131

132132
public void testRangeQuery() {

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.apache.lucene.index.IndexOptions;
2323
import org.apache.lucene.index.IndexableField;
2424
import org.apache.lucene.search.MatchAllDocsQuery;
25+
import org.apache.lucene.search.MultiTermQuery;
2526
import org.apache.lucene.search.Query;
2627
import org.apache.lucene.util.BytesRef;
2728
import org.elasticsearch.Version;
@@ -155,7 +156,9 @@ public Query termsQuery(List values, QueryShardContext context) {
155156
}
156157

157158
@Override
158-
public Query wildcardQuery(String value, QueryShardContext context) {
159+
public Query wildcardQuery(String value,
160+
@Nullable MultiTermQuery.RewriteMethod method,
161+
QueryShardContext context) {
159162
if (isSameIndex(value, context.getFullyQualifiedIndex().getName())) {
160163
return Queries.newMatchAllQuery();
161164
} else {

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,9 @@ public Query prefixQuery(String value, @Nullable MultiTermQuery.RewriteMethod me
367367
throw new QueryShardException(context, "Can only use prefix queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]");
368368
}
369369

370-
public Query wildcardQuery(String value, QueryShardContext context) {
370+
public Query wildcardQuery(String value,
371+
@Nullable MultiTermQuery.RewriteMethod method,
372+
QueryShardContext context) {
371373
throw new QueryShardException(context, "Can only use wildcard queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]");
372374
}
373375

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import org.elasticsearch.common.lucene.BytesRefs;
4040
import org.elasticsearch.common.unit.Fuzziness;
4141
import org.elasticsearch.index.query.QueryShardContext;
42+
import org.elasticsearch.index.query.support.QueryParsers;
4243

4344
import java.io.IOException;
4445
import java.util.ArrayList;
@@ -85,13 +86,16 @@ public Query prefixQuery(String value, MultiTermQuery.RewriteMethod method, Quer
8586
}
8687

8788
@Override
88-
public Query wildcardQuery(String value, QueryShardContext context) {
89+
public Query wildcardQuery(String value, MultiTermQuery.RewriteMethod method, QueryShardContext context) {
8990
Query termQuery = termQuery(value, context);
9091
if (termQuery instanceof MatchNoDocsQuery || termQuery instanceof MatchAllDocsQuery) {
9192
return termQuery;
9293
}
9394
Term term = MappedFieldType.extractTerm(termQuery);
94-
return new WildcardQuery(term);
95+
96+
WildcardQuery query = new WildcardQuery(term);
97+
QueryParsers.setRewriteMethod(query, method);
98+
return query;
9599
}
96100

97101
@Override

server/src/main/java/org/elasticsearch/index/query/WildcardQueryBuilder.java

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,14 @@
1919

2020
package org.elasticsearch.index.query;
2121

22-
import org.apache.lucene.index.Term;
22+
import org.apache.lucene.search.MatchNoDocsQuery;
2323
import org.apache.lucene.search.MultiTermQuery;
2424
import org.apache.lucene.search.Query;
25-
import org.apache.lucene.search.WildcardQuery;
2625
import org.elasticsearch.common.ParseField;
2726
import org.elasticsearch.common.ParsingException;
2827
import org.elasticsearch.common.Strings;
2928
import org.elasticsearch.common.io.stream.StreamInput;
3029
import org.elasticsearch.common.io.stream.StreamOutput;
31-
import org.elasticsearch.common.lucene.BytesRefs;
3230
import org.elasticsearch.common.xcontent.LoggingDeprecationHandler;
3331
import org.elasticsearch.common.xcontent.XContentBuilder;
3432
import org.elasticsearch.common.xcontent.XContentParser;
@@ -185,20 +183,13 @@ public static WildcardQueryBuilder fromXContent(XContentParser parser) throws IO
185183
protected Query doToQuery(QueryShardContext context) throws IOException {
186184
MappedFieldType fieldType = context.fieldMapper(fieldName);
187185

188-
Query query;
189186
if (fieldType == null) {
190-
Term term = new Term(fieldName, BytesRefs.toBytesRef(value));
191-
query = new WildcardQuery(term);
192-
} else {
193-
query = fieldType.wildcardQuery(value, context);
187+
return new MatchNoDocsQuery("unknown field [" + fieldName + "]");
194188
}
195189

196-
if (query instanceof MultiTermQuery) {
197-
MultiTermQuery.RewriteMethod rewriteMethod = QueryParsers.parseRewriteMethod(
198-
rewrite, null, LoggingDeprecationHandler.INSTANCE);
199-
QueryParsers.setRewriteMethod((MultiTermQuery) query, rewriteMethod);
200-
}
201-
return query;
190+
MultiTermQuery.RewriteMethod method = QueryParsers.parseRewriteMethod(
191+
rewrite, null, LoggingDeprecationHandler.INSTANCE);
192+
return fieldType.wildcardQuery(value, method, context);
202193
}
203194

204195
@Override

server/src/test/java/org/elasticsearch/index/query/WildcardQueryBuilderTests.java

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
package org.elasticsearch.index.query;
2121

22-
import org.apache.lucene.index.Term;
2322
import org.apache.lucene.search.MatchAllDocsQuery;
2423
import org.apache.lucene.search.MatchNoDocsQuery;
2524
import org.apache.lucene.search.Query;
@@ -70,13 +69,19 @@ private static WildcardQueryBuilder randomWildcardQuery() {
7069

7170
@Override
7271
protected void doAssertLuceneQuery(WildcardQueryBuilder queryBuilder, Query query, SearchContext context) throws IOException {
73-
assertThat(query, instanceOf(WildcardQuery.class));
74-
WildcardQuery wildcardQuery = (WildcardQuery) query;
75-
7672
String expectedFieldName = expectedFieldName(queryBuilder.fieldName());
77-
assertThat(wildcardQuery.getField(), equalTo(expectedFieldName));
78-
assertThat(wildcardQuery.getTerm().field(), equalTo(expectedFieldName));
79-
assertThat(wildcardQuery.getTerm().text(), equalTo(queryBuilder.value()));
73+
74+
if (expectedFieldName.equals(STRING_FIELD_NAME)) {
75+
assertThat(query, instanceOf(WildcardQuery.class));
76+
WildcardQuery wildcardQuery = (WildcardQuery) query;
77+
78+
assertThat(wildcardQuery.getField(), equalTo(expectedFieldName));
79+
assertThat(wildcardQuery.getTerm().field(), equalTo(expectedFieldName));
80+
assertThat(wildcardQuery.getTerm().text(), equalTo(queryBuilder.value()));
81+
} else {
82+
Query expected = new MatchNoDocsQuery("unknown field [" + expectedFieldName + "]");
83+
assertEquals(expected, query);
84+
}
8085
}
8186

8287
public void testIllegalArguments() {
@@ -92,7 +97,7 @@ public void testIllegalArguments() {
9297
public void testEmptyValue() throws IOException {
9398
QueryShardContext context = createShardContext();
9499
context.setAllowUnmappedFields(true);
95-
WildcardQueryBuilder wildcardQueryBuilder = new WildcardQueryBuilder("doc", "");
100+
WildcardQueryBuilder wildcardQueryBuilder = new WildcardQueryBuilder(STRING_FIELD_NAME, "");
96101
assertEquals(wildcardQueryBuilder.toQuery(context).getClass(), WildcardQuery.class);
97102
}
98103

@@ -130,16 +135,6 @@ public void testParseFailsWithMultipleFields() throws IOException {
130135
assertEquals("[wildcard] query doesn't support multiple fields, found [user1] and [user2]", e.getMessage());
131136
}
132137

133-
public void testWithMetaDataField() throws IOException {
134-
QueryShardContext context = createShardContext();
135-
for (String field : new String[]{"field1", "field2"}) {
136-
WildcardQueryBuilder wildcardQueryBuilder = new WildcardQueryBuilder(field, "toto");
137-
Query query = wildcardQueryBuilder.toQuery(context);
138-
Query expected = new WildcardQuery(new Term(field, "toto"));
139-
assertEquals(expected, query);
140-
}
141-
}
142-
143138
public void testIndexWildcard() throws IOException {
144139
assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);
145140

0 commit comments

Comments
 (0)