Wildcard field bug fix for prefix + term queries. Wildcard syntax should not be supported. (#62085) (#62154)
Wildcard field bug fix for term and prefix queries. We now escape any * or ? characters in the search string before delegating to the main wildcardQuery() method. Closes #62081
This commit is contained in:
parent
6c1700c343
commit
5a48895065
|
@ -250,7 +250,7 @@ setup:
|
|||
query:
|
||||
prefix:
|
||||
my_wildcard:
|
||||
value: "hell*"
|
||||
value: "hell"
|
||||
|
||||
|
||||
- match: {hits.total.value: 1}
|
||||
|
|
|
@ -844,12 +844,28 @@ public class WildcardFieldMapper extends FieldMapper {
|
|||
|
||||
@Override
|
||||
public Query termQuery(Object value, QueryShardContext context) {
|
||||
return wildcardQuery(BytesRefs.toString(value), MultiTermQuery.CONSTANT_SCORE_REWRITE, context);
|
||||
String searchTerm = BytesRefs.toString(value);
|
||||
return wildcardQuery(escapeWildcardSyntax(searchTerm), MultiTermQuery.CONSTANT_SCORE_REWRITE, context);
|
||||
}
|
||||
|
||||
private String escapeWildcardSyntax(String term) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (int i = 0; i < term.length();) {
|
||||
final int c = term.codePointAt(i);
|
||||
int length = Character.charCount(c);
|
||||
// Escape any reserved characters
|
||||
if (c == WildcardQuery.WILDCARD_STRING || c == WildcardQuery.WILDCARD_CHAR || c == WildcardQuery.WILDCARD_ESCAPE) {
|
||||
result.append("\\");
|
||||
}
|
||||
result.appendCodePoint(c);
|
||||
i += length;
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query prefixQuery(String value, MultiTermQuery.RewriteMethod method, QueryShardContext context) {
|
||||
return wildcardQuery(value + "*", method, context);
|
||||
return wildcardQuery(escapeWildcardSyntax(value) + "*", method, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -178,6 +178,47 @@ public class WildcardFieldMapperTests extends ESTestCase {
|
|||
reader.close();
|
||||
dir.close();
|
||||
}
|
||||
|
||||
|
||||
public void testTermAndPrefixQueryIgnoreWildcardSyntax() throws IOException {
|
||||
Directory dir = newDirectory();
|
||||
IndexWriterConfig iwc = newIndexWriterConfig(WildcardFieldMapper.WILDCARD_ANALYZER);
|
||||
iwc.setMergePolicy(newTieredMergePolicy(random()));
|
||||
RandomIndexWriter iw = new RandomIndexWriter(random(), dir, iwc);
|
||||
|
||||
Document doc = new Document();
|
||||
ParseContext.Document parseDoc = new ParseContext.Document();
|
||||
addFields(parseDoc, doc, "f*oo?");
|
||||
indexDoc(parseDoc, doc, iw);
|
||||
|
||||
iw.forceMerge(1);
|
||||
DirectoryReader reader = iw.getReader();
|
||||
IndexSearcher searcher = newSearcher(reader);
|
||||
iw.close();
|
||||
|
||||
expectTermMatch(searcher, "f*oo*", 0);
|
||||
expectTermMatch(searcher, "f*oo?", 1);
|
||||
expectTermMatch(searcher, "*oo?", 0);
|
||||
|
||||
expectPrefixMatch(searcher, "f*o", 1);
|
||||
expectPrefixMatch(searcher, "f*oo?", 1);
|
||||
expectPrefixMatch(searcher, "f??o", 0);
|
||||
|
||||
reader.close();
|
||||
dir.close();
|
||||
}
|
||||
|
||||
private void expectTermMatch(IndexSearcher searcher, String term,long count) throws IOException {
|
||||
Query q = wildcardFieldType.fieldType().termQuery(term, MOCK_QSC);
|
||||
TopDocs td = searcher.search(q, 10, Sort.RELEVANCE);
|
||||
assertThat(td.totalHits.value, equalTo(count));
|
||||
}
|
||||
|
||||
private void expectPrefixMatch(IndexSearcher searcher, String term,long count) throws IOException {
|
||||
Query q = wildcardFieldType.fieldType().prefixQuery(term, null, MOCK_QSC);
|
||||
TopDocs td = searcher.search(q, 10, Sort.RELEVANCE);
|
||||
assertThat(td.totalHits.value, equalTo(count));
|
||||
}
|
||||
|
||||
|
||||
public void testSearchResultsVersusKeywordField() throws IOException {
|
||||
|
|
Loading…
Reference in New Issue