Repository navigation
Conversation
|
Pinging @elastic/es-search-relevance (Team:Search Relevance) |
| Automaton automaton; | ||
| try { | ||
| automaton = WildcardQuery.toAutomaton(new Term(name(), matchPattern), Operations.DEFAULT_DETERMINIZE_WORK_LIMIT); | ||
| } catch (TooComplexToDeterminizeException e) { | ||
| throw new IllegalArgumentException("Pattern was too complex to determinize", e); | ||
| } |
There was a problem hiding this comment.
let's do the same thing that was done in the KeywordFieldMapper. So something like:
Term term = new Term(name(), value);
if (context.getCircuitBreaker() != null) {
Automaton dfa = AutomatonQueries.toWildcardAutomaton(term, context.getCircuitBreaker());
return new AutomatonQuery(term, dfa, false, MultiTermQuery.DOC_VALUES_REWRITE);
}
return new WildcardQuery(term, Operations.DEFAULT_DETERMINIZE_WORK_LIMIT, MultiTermQuery.DOC_VALUES_REWRITE);
There was a problem hiding this comment.
Done — switched to AutomatonQueries.toWildcardAutomaton(term, circuitBreaker) so the NFA→DFA determinization heap is tracked alongside the other wildcard queries.
One deviation worth flagging: constant_keyword has no Lucene index (ConstantFieldType uses IndexType.NONE; parseCreateField doesn't write the value), so returning an AutomatonQuery / WildcardQuery against the field would scan an empty index and always return zero docs. I kept the in-memory CharacterRunAutomaton.run(value) → ALL_DOCS_INSTANCE / NO_DOCS_INSTANCE shape, matching the existing ConstantFieldType#automatonQuery pattern and the rest of the matches()-based queries on this type. Happy to switch approach if you'd prefer something else.
ConstantKeywordFieldType#matches uses Regex.simpleMatch, which only treats * as a wildcard. The wildcard query DSL also defines ? as matching exactly one character, so patterns like f?o failed against constant values that should match. Override wildcardQuery on the constant_keyword field type to use Lucene's WildcardQuery automaton, matching the semantics of other text field types. Also drop the final modifier from ConstantFieldType#wildcardQuery so constant-value field types can supply their own matcher when simpleMatch semantics are wrong for them. Closes elastic#141785
Compile via AutomatonQueries.toWildcardAutomaton when the SearchExecutionContext exposes a circuit breaker, so the NFA->DFA determinization heap is tracked alongside other wildcard queries. Falls back to work-limit-only WildcardQuery.toAutomaton when no breaker is available (e.g. coordinator rewrite paths).
02c9d65 to
43ecc0b
Compare
|
buildkite test this please |
|
Thank you for the contribution @daguimu! |
Problem
A
wildcardquery against aconstant_keywordfield treats?as a literal character instead of "match exactly one character". Per the wildcard query docs,?and*are both wildcard metacharacters.f*o*and other patterns containing only*work as expected — only?is broken.Root Cause
ConstantFieldType#wildcardQuery(final) delegates to the abstractmatches(String pattern, boolean caseInsensitive, QueryRewriteContext).ConstantKeywordFieldType#matchesis implemented withRegex.simpleMatch, which only handles*(per its own Javadoc — "xxx*", "xxx", "xxx", "xxxyyy"). When the pattern contains?,simpleMatchfalls through to literal equality and returnsfalse.The same
matches()is reused bytermQuery/termsQuery/prefixQuerywhere?should remain literal, so we cannot simply changematches()to honour?.Fix
ConstantFieldType#wildcardQuery(String, boolean, QueryRewriteContext): dropfinalso subclasses can plug in their own wildcard matcher whensimpleMatchsemantics are wrong for them. The default still callsmatches(), so behaviour for_index,_index_mode,_tier, etc. is unchanged.ConstantKeywordFieldType: overridewildcardQueryto compile the pattern withWildcardQuery.toAutomatonand run the resultingCharacterRunAutomatonagainst the constant value. This mirrors whatIndexFieldTypealready does for itswildcardLikeQuerypath.Tests Added
?matches exactly one character (f?o,???,f?o*)ConstantKeywordFieldTypeTests#testWildcardQueryWithQuestionMark?matches exactly one —f?does not matchfoonullconstant value short-circuits toNO_DOCSThe pre-existing
testWildcardQuerycontinues to cover*-only patterns and case-insensitive matching.Impact
wildcardqueries againstconstant_keywordfields now honour?as a single-character wildcard, matching the documented semantics.term,terms,prefix, orregexpqueries onconstant_keyword.Closes #141785