Skip to content

Commit 4e68ecc

Browse files
authored
Use DV rewrites where possible in Keyword queries (#137536)
Keyword automaton queries against doc-values-only fields can use standard MultiTermQuery implementations with DOC_VALUES_REWRITE rewrite methods. These should be considerably faster and more efficient than the scripted query implementations.
1 parent e20a629 commit 4e68ecc

File tree

2 files changed

+29
-21
lines changed

2 files changed

+29
-21
lines changed

docs/changelog/137536.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 137536
2+
summary: Use DV rewrites where possible in Keyword queries
3+
area: Search
4+
type: enhancement
5+
issues: []

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

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,12 @@
2727
import org.apache.lucene.index.Term;
2828
import org.apache.lucene.index.Terms;
2929
import org.apache.lucene.index.TermsEnum;
30+
import org.apache.lucene.search.FuzzyQuery;
3031
import org.apache.lucene.search.MultiTermQuery;
32+
import org.apache.lucene.search.PrefixQuery;
3133
import org.apache.lucene.search.Query;
34+
import org.apache.lucene.search.RegexpQuery;
35+
import org.apache.lucene.search.WildcardQuery;
3236
import org.apache.lucene.util.BytesRef;
3337
import org.apache.lucene.util.automaton.Automata;
3438
import org.apache.lucene.util.automaton.Automaton;
@@ -67,9 +71,7 @@
6771
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
6872
import org.elasticsearch.search.lookup.FieldValues;
6973
import org.elasticsearch.search.lookup.SearchLookup;
70-
import org.elasticsearch.search.runtime.StringScriptFieldFuzzyQuery;
7174
import org.elasticsearch.search.runtime.StringScriptFieldPrefixQuery;
72-
import org.elasticsearch.search.runtime.StringScriptFieldRegexpQuery;
7375
import org.elasticsearch.search.runtime.StringScriptFieldTermQuery;
7476
import org.elasticsearch.search.runtime.StringScriptFieldWildcardQuery;
7577
import org.elasticsearch.xcontent.Text;
@@ -720,14 +722,13 @@ public Query fuzzyQuery(
720722
if (indexType.hasTerms()) {
721723
return super.fuzzyQuery(value, fuzziness, prefixLength, maxExpansions, transpositions, context, rewriteMethod);
722724
} else {
723-
return StringScriptFieldFuzzyQuery.build(
724-
new Script(""),
725-
ctx -> new SortedSetDocValuesStringFieldScript(name(), context.lookup(), ctx),
726-
name(),
727-
indexedValueForSearch(value).utf8ToString(),
725+
return new FuzzyQuery(
726+
new Term(name(), indexedValueForSearch(value)),
728727
fuzziness.asDistance(BytesRefs.toString(value)),
729728
prefixLength,
730-
transpositions
729+
maxExpansions,
730+
transpositions,
731+
MultiTermQuery.DOC_VALUES_REWRITE
731732
);
732733
}
733734
}
@@ -743,6 +744,10 @@ public Query prefixQuery(
743744
if (indexType.hasTerms()) {
744745
return super.prefixQuery(value, method, caseInsensitive, context);
745746
} else {
747+
if (caseInsensitive == false) {
748+
Term prefix = new Term(name(), indexedValueForSearch(value));
749+
return new PrefixQuery(prefix, MultiTermQuery.DOC_VALUES_REWRITE);
750+
}
746751
return new StringScriptFieldPrefixQuery(
747752
new Script(""),
748753
ctx -> new SortedSetDocValuesStringFieldScript(name(), context.lookup(), ctx),
@@ -1017,6 +1022,10 @@ public Query wildcardQuery(
10171022
} else {
10181023
value = indexedValueForSearch(value).utf8ToString();
10191024
}
1025+
if (caseInsensitive == false) {
1026+
Term term = new Term(name(), value);
1027+
return new WildcardQuery(term, Operations.DEFAULT_DETERMINIZE_WORK_LIMIT, MultiTermQuery.DOC_VALUES_REWRITE);
1028+
}
10201029
return new StringScriptFieldWildcardQuery(
10211030
new Script(""),
10221031
ctx -> new SortedSetDocValuesStringFieldScript(name(), context.lookup(), ctx),
@@ -1038,13 +1047,8 @@ public Query normalizedWildcardQuery(String value, MultiTermQuery.RewriteMethod
10381047
} else {
10391048
value = indexedValueForSearch(value).utf8ToString();
10401049
}
1041-
return new StringScriptFieldWildcardQuery(
1042-
new Script(""),
1043-
ctx -> new SortedSetDocValuesStringFieldScript(name(), context.lookup(), ctx),
1044-
name(),
1045-
value,
1046-
false
1047-
);
1050+
Term term = new Term(name(), value);
1051+
return new WildcardQuery(term, Operations.DEFAULT_DETERMINIZE_WORK_LIMIT, MultiTermQuery.DOC_VALUES_REWRITE);
10481052
}
10491053
}
10501054

@@ -1064,14 +1068,13 @@ public Query regexpQuery(
10641068
if (matchFlags != 0) {
10651069
throw new IllegalArgumentException("Match flags not yet implemented [" + matchFlags + "]");
10661070
}
1067-
return new StringScriptFieldRegexpQuery(
1068-
new Script(""),
1069-
ctx -> new SortedSetDocValuesStringFieldScript(name(), context.lookup(), ctx),
1070-
name(),
1071-
indexedValueForSearch(value).utf8ToString(),
1071+
return new RegexpQuery(
1072+
new Term(name(), indexedValueForSearch(value)),
10721073
syntaxFlags,
10731074
matchFlags,
1074-
maxDeterminizedStates
1075+
RegexpQuery.DEFAULT_PROVIDER,
1076+
maxDeterminizedStates,
1077+
MultiTermQuery.DOC_VALUES_REWRITE
10751078
);
10761079
}
10771080
}

0 commit comments

Comments
 (0)