Skip to content

Commit 7ee4ea8

Browse files
committed
Fixed QueryParsingException in multi match query when a wildcard expression results in no fields.
The query will now return 0 hits (null query) instead of throwing an exception. This matches the behavior if a nonexistent field is specified. These changes were backported from latest master (mostly from elastic#13405).
1 parent ae18f35 commit 7ee4ea8

File tree

2 files changed

+27
-13
lines changed

2 files changed

+27
-13
lines changed

core/src/main/java/org/elasticsearch/index/query/MultiMatchQueryParser.java

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,14 @@
2727
import org.elasticsearch.common.regex.Regex;
2828
import org.elasticsearch.common.unit.Fuzziness;
2929
import org.elasticsearch.common.xcontent.XContentParser;
30+
import org.elasticsearch.index.mapper.MapperService;
3031
import org.elasticsearch.index.query.support.QueryParsers;
3132
import org.elasticsearch.index.search.MatchQuery;
3233
import org.elasticsearch.index.search.MultiMatchQuery;
3334

3435
import java.io.IOException;
3536
import java.util.Map;
37+
import java.util.TreeMap;
3638

3739
/**
3840
* Same as {@link MatchQueryParser} but has support for multiple fields.
@@ -73,10 +75,10 @@ public Query parse(QueryParseContext parseContext) throws IOException, QueryPars
7375
} else if ("fields".equals(currentFieldName)) {
7476
if (token == XContentParser.Token.START_ARRAY) {
7577
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
76-
extractFieldAndBoost(parseContext, parser, fieldNameWithBoosts);
78+
parseFieldAndBoost(parser, fieldNameWithBoosts);
7779
}
7880
} else if (token.isValue()) {
79-
extractFieldAndBoost(parseContext, parser, fieldNameWithBoosts);
81+
parseFieldAndBoost(parser, fieldNameWithBoosts);
8082
} else {
8183
throw new QueryParsingException(parseContext, "[" + NAME + "] query does not support [" + currentFieldName + "]");
8284
}
@@ -160,7 +162,10 @@ public Query parse(QueryParseContext parseContext) throws IOException, QueryPars
160162
}
161163
}
162164
}
163-
Query query = multiMatchQuery.parse(type, fieldNameWithBoosts, value, minimumShouldMatch);
165+
166+
Map<String, Float> newFieldsBoosts = handleFieldsMatchPattern(parseContext.mapperService(), fieldNameWithBoosts);
167+
168+
Query query = multiMatchQuery.parse(type, newFieldsBoosts, value, minimumShouldMatch);
164169
if (query == null) {
165170
return null;
166171
}
@@ -172,7 +177,23 @@ public Query parse(QueryParseContext parseContext) throws IOException, QueryPars
172177
return query;
173178
}
174179

175-
private void extractFieldAndBoost(QueryParseContext parseContext, XContentParser parser, Map<String, Float> fieldNameWithBoosts) throws IOException {
180+
private static Map<String, Float> handleFieldsMatchPattern(MapperService mapperService, Map<String, Float> fieldsBoosts) {
181+
Map<String, Float> newFieldsBoosts = new TreeMap<>();
182+
for (Map.Entry<String, Float> fieldBoost : fieldsBoosts.entrySet()) {
183+
String fField = fieldBoost.getKey();
184+
Float fBoost = fieldBoost.getValue();
185+
if (Regex.isSimpleMatchPattern(fField)) {
186+
for (String field : mapperService.simpleMatchToIndexNames(fField)) {
187+
newFieldsBoosts.put(field, fBoost);
188+
}
189+
} else {
190+
newFieldsBoosts.put(fField, fBoost);
191+
}
192+
}
193+
return newFieldsBoosts;
194+
}
195+
196+
private static void parseFieldAndBoost(XContentParser parser, Map<String, Float> fieldsBoosts) throws IOException {
176197
String fField = null;
177198
Float fBoost = null;
178199
char[] fieldText = parser.textCharacters();
@@ -188,13 +209,6 @@ private void extractFieldAndBoost(QueryParseContext parseContext, XContentParser
188209
if (fField == null) {
189210
fField = parser.text();
190211
}
191-
192-
if (Regex.isSimpleMatchPattern(fField)) {
193-
for (String field : parseContext.mapperService().simpleMatchToIndexNames(fField)) {
194-
fieldNameWithBoosts.put(field, fBoost);
195-
}
196-
} else {
197-
fieldNameWithBoosts.put(fField, fBoost);
198-
}
212+
fieldsBoosts.put(fField, fBoost);
199213
}
200214
}

core/src/test/java/org/elasticsearch/search/query/MultiMatchQueryIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ public void testSingleField() throws NoSuchFieldException, IllegalAccessExceptio
221221
assertNoFailures(searchResponse);
222222
assertFirstHit(searchResponse, hasId("theone"));
223223

224-
String[] fields = {"full_name", "first_name", "last_name", "last_name_phrase", "first_name_phrase", "category_phrase", "category"};
224+
String[] fields = {"full_name", "first_name", "last_name", "last_name_phrase", "first_name_phrase", "category_phrase", "category", "missing_field", "missing_fields*"};
225225

226226
String[] query = {"marvel","hero", "captain", "america", "15", "17", "1", "5", "ultimate", "Man",
227227
"marvel", "wolferine", "ninja"};

0 commit comments

Comments
 (0)