Skip to content

Commit e2c64d9

Browse files
jtibshiranikcm
authored andcommitted
Delegate wildcard query creation to MappedFieldType. (#34062)
* Delegate wildcard query creation to MappedFieldType. * Disallow wildcard queries on collation fields. * Disallow wildcard queries on non-string fields.
1 parent 8d99925 commit e2c64d9

File tree

6 files changed

+53
-17
lines changed

6 files changed

+53
-17
lines changed

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import com.ibm.icu.text.RawCollationKey;
2424
import com.ibm.icu.text.RuleBasedCollator;
2525
import com.ibm.icu.util.ULocale;
26-
2726
import org.apache.lucene.document.Field;
2827
import org.apache.lucene.document.SortedSetDocValuesField;
2928
import org.apache.lucene.index.IndexOptions;
@@ -159,18 +158,23 @@ protected BytesRef indexedValueForSearch(Object value) {
159158
@Override
160159
public Query fuzzyQuery(Object value, Fuzziness fuzziness, int prefixLength, int maxExpansions,
161160
boolean transpositions) {
162-
throw new UnsupportedOperationException();
161+
throw new UnsupportedOperationException("[fuzzy] queries are not supported on [" + CONTENT_TYPE + "] fields.");
163162
}
164163

165164
@Override
166165
public Query prefixQuery(String value, MultiTermQuery.RewriteMethod method, QueryShardContext context) {
167-
throw new UnsupportedOperationException();
166+
throw new UnsupportedOperationException("[prefix] queries are not supported on [" + CONTENT_TYPE + "] fields.");
167+
}
168+
169+
@Override
170+
public Query wildcardQuery(String value, QueryShardContext context) {
171+
throw new UnsupportedOperationException("[wildcard] queries are not supported on [" + CONTENT_TYPE + "] fields.");
168172
}
169173

170174
@Override
171175
public Query regexpQuery(String value, int flags, int maxDeterminizedStates,
172176
MultiTermQuery.RewriteMethod method, QueryShardContext context) {
173-
throw new UnsupportedOperationException();
177+
throw new UnsupportedOperationException("[regexp] queries are not supported on [" + CONTENT_TYPE + "] fields.");
174178
}
175179

176180
public static DocValueFormat COLLATE_FORMAT = new DocValueFormat() {

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,14 @@ public void testPrefixQuery() {
121121
() -> ft.prefixQuery("prefix", null, null));
122122
}
123123

124+
public void testWildcardQuery() {
125+
MappedFieldType ft = createDefaultFieldType();
126+
ft.setName("field");
127+
ft.setIndexOptions(IndexOptions.DOCS);
128+
expectThrows(UnsupportedOperationException.class,
129+
() -> ft.wildcardQuery("foo*", null));
130+
}
131+
124132
public void testRangeQuery() {
125133
MappedFieldType ft = createDefaultFieldType();
126134
ft.setName("field");

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,17 @@ public Query termsQuery(List values, QueryShardContext context) {
150150
+ " vs. " + values);
151151
}
152152

153+
@Override
154+
public Query wildcardQuery(String value, QueryShardContext context) {
155+
if (isSameIndex(value, context.getFullyQualifiedIndex().getName())) {
156+
return Queries.newMatchAllQuery();
157+
} else {
158+
return Queries.newMatchNoDocsQuery("Index didn't match. Index queried: " + context.index().getName() + " vs. " + value);
159+
}
160+
}
161+
153162
private boolean isSameIndex(Object value, String indexName) {
154-
String pattern = value instanceof BytesRef ? pattern = ((BytesRef) value).utf8ToString() : value.toString();
163+
String pattern = value instanceof BytesRef ? ((BytesRef) value).utf8ToString() : value.toString();
155164
return Regex.simpleMatch(pattern, indexName);
156165
}
157166

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,10 @@ public Query prefixQuery(String value, @Nullable MultiTermQuery.RewriteMethod me
345345
throw new QueryShardException(context, "Can only use prefix queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]");
346346
}
347347

348+
public Query wildcardQuery(String value, QueryShardContext context) {
349+
throw new QueryShardException(context, "Can only use wildcard queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]");
350+
}
351+
348352
public Query regexpQuery(String value, int flags, int maxDeterminizedStates, @Nullable MultiTermQuery.RewriteMethod method, QueryShardContext context) {
349353
throw new QueryShardException(context, "Can only use regexp queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]");
350354
}

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,16 @@
2222
import java.util.List;
2323

2424
import org.apache.lucene.index.Term;
25+
import org.apache.lucene.search.MatchAllDocsQuery;
26+
import org.apache.lucene.search.MatchNoDocsQuery;
2527
import org.apache.lucene.search.TermInSetQuery;
2628
import org.apache.lucene.search.FuzzyQuery;
2729
import org.apache.lucene.search.MultiTermQuery;
2830
import org.apache.lucene.search.PrefixQuery;
2931
import org.apache.lucene.search.Query;
3032
import org.apache.lucene.search.RegexpQuery;
3133
import org.apache.lucene.search.TermRangeQuery;
34+
import org.apache.lucene.search.WildcardQuery;
3235
import org.apache.lucene.util.BytesRef;
3336
import org.elasticsearch.common.lucene.BytesRefs;
3437
import org.elasticsearch.common.unit.Fuzziness;
@@ -74,6 +77,16 @@ public Query prefixQuery(String value, MultiTermQuery.RewriteMethod method, Quer
7477
return query;
7578
}
7679

80+
@Override
81+
public Query wildcardQuery(String value, QueryShardContext context) {
82+
Query termQuery = termQuery(value, context);
83+
if (termQuery instanceof MatchNoDocsQuery || termQuery instanceof MatchAllDocsQuery) {
84+
return termQuery;
85+
}
86+
Term term = MappedFieldType.extractTerm(termQuery);
87+
return new WildcardQuery(term);
88+
}
89+
7790
@Override
7891
public Query regexpQuery(String value, int flags, int maxDeterminizedStates,
7992
MultiTermQuery.RewriteMethod method, QueryShardContext context) {

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

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020
package org.elasticsearch.index.query;
2121

2222
import org.apache.lucene.index.Term;
23-
import org.apache.lucene.search.MatchAllDocsQuery;
24-
import org.apache.lucene.search.MatchNoDocsQuery;
2523
import org.apache.lucene.search.MultiTermQuery;
2624
import org.apache.lucene.search.Query;
2725
import org.apache.lucene.search.WildcardQuery;
@@ -185,20 +183,20 @@ public static WildcardQueryBuilder fromXContent(XContentParser parser) throws IO
185183
@Override
186184
protected Query doToQuery(QueryShardContext context) throws IOException {
187185
MappedFieldType fieldType = context.fieldMapper(fieldName);
188-
Term term;
186+
187+
Query query;
189188
if (fieldType == null) {
190-
term = new Term(fieldName, BytesRefs.toBytesRef(value));
189+
Term term = new Term(fieldName, BytesRefs.toBytesRef(value));
190+
query = new WildcardQuery(term);
191191
} else {
192-
Query termQuery = fieldType.termQuery(value, context);
193-
if (termQuery instanceof MatchNoDocsQuery || termQuery instanceof MatchAllDocsQuery) {
194-
return termQuery;
195-
}
196-
term = MappedFieldType.extractTerm(termQuery);
192+
query = fieldType.wildcardQuery(value, context);
197193
}
198194

199-
WildcardQuery query = new WildcardQuery(term);
200-
MultiTermQuery.RewriteMethod rewriteMethod = QueryParsers.parseRewriteMethod(rewrite, null, LoggingDeprecationHandler.INSTANCE);
201-
QueryParsers.setRewriteMethod(query, rewriteMethod);
195+
if (query instanceof MultiTermQuery) {
196+
MultiTermQuery.RewriteMethod rewriteMethod = QueryParsers.parseRewriteMethod(
197+
rewrite, null, LoggingDeprecationHandler.INSTANCE);
198+
QueryParsers.setRewriteMethod((MultiTermQuery) query, rewriteMethod);
199+
}
202200
return query;
203201
}
204202

0 commit comments

Comments
 (0)