Search fix: query_string regex/wildcard searches not working on wildcard fields (#60959) (#61010)

The Query string parser was not delegating the construction of wildcard/regex queries to the underlying field type.
The wildcard field has special data structures and queries that operate on them so cannot rely on the basic regex/wildcard queries that were being used for other fields.

Closes #60957
This commit is contained in:
markharwood 2020-08-12 10:44:52 +01:00 committed by GitHub
parent 32423a486d
commit 66098e0bf4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 56 additions and 8 deletions

View File

@ -43,6 +43,7 @@ import org.apache.lucene.search.spans.SpanNearQuery;
import org.apache.lucene.search.spans.SpanOrQuery; import org.apache.lucene.search.spans.SpanOrQuery;
import org.apache.lucene.search.spans.SpanQuery; import org.apache.lucene.search.spans.SpanQuery;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.automaton.RegExp;
import org.elasticsearch.common.lucene.search.Queries; import org.elasticsearch.common.lucene.search.Queries;
import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.regex.Regex;
import org.elasticsearch.common.unit.Fuzziness; import org.elasticsearch.common.unit.Fuzziness;
@ -669,15 +670,19 @@ public class QueryStringQueryParser extends XQueryParser {
// effectively, we check if a field exists or not // effectively, we check if a field exists or not
return existsQuery(field); return existsQuery(field);
} }
String indexedNameField = field;
Analyzer oldAnalyzer = getAnalyzer(); Analyzer oldAnalyzer = getAnalyzer();
try { try {
MappedFieldType currentFieldType = queryBuilder.context.fieldMapper(field); MappedFieldType currentFieldType = queryBuilder.context.fieldMapper(field);
if (currentFieldType != null) { if (currentFieldType == null) {
setAnalyzer(forceAnalyzer == null ? queryBuilder.context.getSearchAnalyzer(currentFieldType) : forceAnalyzer); return newUnmappedFieldQuery(field);
indexedNameField = currentFieldType.name();
} }
return super.getWildcardQuery(indexedNameField, termStr); if (forceAnalyzer != null &&
(analyzeWildcard || currentFieldType.getTextSearchInfo().isTokenized())) {
setAnalyzer(forceAnalyzer);
return super.getWildcardQuery(currentFieldType.name(), termStr);
}
return currentFieldType.wildcardQuery(termStr, getMultiTermRewriteMethod(), context);
} catch (RuntimeException e) { } catch (RuntimeException e) {
if (lenient) { if (lenient) {
return newLenientFieldQuery(field, e); return newLenientFieldQuery(field, e);
@ -722,9 +727,12 @@ public class QueryStringQueryParser extends XQueryParser {
if (currentFieldType == null) { if (currentFieldType == null) {
return newUnmappedFieldQuery(field); return newUnmappedFieldQuery(field);
} }
setAnalyzer(forceAnalyzer == null ? queryBuilder.context.getSearchAnalyzer(currentFieldType) : forceAnalyzer); if (forceAnalyzer != null) {
Query query = super.getRegexpQuery(field, termStr); setAnalyzer(forceAnalyzer);
return query; return super.getRegexpQuery(field, termStr);
}
return currentFieldType.regexpQuery(termStr, RegExp.ALL, getMaxDeterminizedStates(),
getMultiTermRewriteMethod(), context);
} catch (RuntimeException e) { } catch (RuntimeException e) {
if (lenient) { if (lenient) {
return newLenientFieldQuery(field, e); return newLenientFieldQuery(field, e);

View File

@ -158,6 +158,46 @@ setup:
- match: {hits.total.value: 1} - match: {hits.total.value: 1}
---
"Query_string prefix query":
- do:
search:
body:
track_total_hits: true
query:
query_string:
query: "hello*"
default_field: "my_wildcard"
- match: {hits.total.value: 1}
---
"Query_string wildcard query":
- do:
search:
body:
track_total_hits: true
query:
query_string:
query: "*orld"
default_field: "my_wildcard"
- match: {hits.total.value: 3}
---
"Query_string regex query":
- do:
search:
body:
track_total_hits: true
query:
query_string:
query: "/hello.*/"
default_field: "my_wildcard"
- match: {hits.total.value: 1}
--- ---
"Term query on wildcard field": "Term query on wildcard field":
- do: - do: