Skip to content

Commit 40ee31b

Browse files
romseygeekKubik42
authored andcommitted
Further simplify SingleValueMatchQuery (elastic#136195)
Rather than doing a two-phase iterator dance with advanceExact, we can use the fact that doc values iterators all extend DocIdSetIterator and reuse DocIdSetIteratorScorerSupplier if we know there are no multi-valued fields in a segment. We can also automatically rewrite to a MatchAllDocsQuery if the input FieldData is a constant value.
1 parent ed4b3ca commit 40ee31b

File tree

3 files changed

+19
-26
lines changed

3 files changed

+19
-26
lines changed

docs/changelog/136195.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 136195
2+
summary: Further simplify `SingleValueMatchQuery`
3+
area: ES|QL
4+
type: enhancement
5+
issues: []

x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/querydsl/query/SingleValueMatchQuery.java

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.elasticsearch.index.fielddata.LeafOrdinalsFieldData;
3636
import org.elasticsearch.index.fielddata.SortedBinaryDocValues;
3737
import org.elasticsearch.index.fielddata.SortedNumericLongValues;
38+
import org.elasticsearch.index.fielddata.plain.ConstantIndexFieldData;
3839

3940
import java.io.IOException;
4041
import java.util.Objects;
@@ -132,15 +133,10 @@ private ScorerSupplier scorerSupplier(
132133
ScoreMode scoreMode
133134
) throws IOException {
134135
final int maxDoc = context.reader().maxDoc();
135-
if (SortedNumericLongValues.unwrapSingleton(sortedNumerics) != null) {
136-
// check for dense field
137-
// TODO: check doc values skippers
138-
final PointValues points = context.reader().getPointValues(fieldData.getFieldName());
139-
if (points != null && points.getDocCount() == maxDoc) {
140-
return new DocIdSetIteratorScorerSupplier(boost, scoreMode, DocIdSetIterator.all(maxDoc));
141-
} else {
142-
return new PredicateScorerSupplier(boost, scoreMode, maxDoc, MULTI_VALUE_MATCH_COST, sortedNumerics::advanceExact);
143-
}
136+
NumericDocValues ndv = DocValues.unwrapSingleton(DocValues.getSortedNumeric(context.reader(), fieldData.getFieldName()));
137+
if (ndv != null && ndv.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) {
138+
ndv = DocValues.unwrapSingleton(DocValues.getSortedNumeric(context.reader(), fieldData.getFieldName()));
139+
return new DocIdSetIteratorScorerSupplier(boost, scoreMode, ndv);
144140
}
145141
final CheckedIntPredicate predicate = doc -> {
146142
if (false == sortedNumerics.advanceExact(doc)) {
@@ -162,21 +158,10 @@ private ScorerSupplier scorerSupplier(
162158
ScoreMode scoreMode
163159
) throws IOException {
164160
final int maxDoc = context.reader().maxDoc();
165-
if (DocValues.unwrapSingleton(sortedSetDocValues) != null) {
166-
// check for dense field
167-
// TODO: check doc values skippers
168-
final Terms terms = context.reader().terms(fieldData.getFieldName());
169-
if (terms != null && terms.getDocCount() == maxDoc) {
170-
return new DocIdSetIteratorScorerSupplier(boost, scoreMode, DocIdSetIterator.all(maxDoc));
171-
} else {
172-
return new PredicateScorerSupplier(
173-
boost,
174-
scoreMode,
175-
maxDoc,
176-
MULTI_VALUE_MATCH_COST,
177-
sortedSetDocValues::advanceExact
178-
);
179-
}
161+
SortedDocValues sdv = DocValues.unwrapSingleton(DocValues.getSortedSet(context.reader(), fieldData.getFieldName()));
162+
if (sdv != null && sdv.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) {
163+
sdv = DocValues.unwrapSingleton(DocValues.getSortedSet(context.reader(), fieldData.getFieldName()));
164+
return new DocIdSetIteratorScorerSupplier(boost, scoreMode, sdv);
180165
}
181166
final CheckedIntPredicate predicate = doc -> {
182167
if (false == sortedSetDocValues.advanceExact(doc)) {
@@ -224,6 +209,9 @@ private ScorerSupplier scorerSupplier(
224209

225210
@Override
226211
public Query rewrite(IndexSearcher indexSearcher) throws IOException {
212+
if (fieldData instanceof ConstantIndexFieldData cfd && cfd.getValue() != null) {
213+
return new MatchAllDocsQuery();
214+
}
227215
for (LeafReaderContext context : indexSearcher.getIndexReader().leaves()) {
228216
final LeafReader reader = context.reader();
229217
final int maxDoc = reader.maxDoc();
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
import static org.hamcrest.Matchers.instanceOf;
4444
import static org.hamcrest.Matchers.sameInstance;
4545

46-
public class SingleValueMathQueryTests extends MapperServiceTestCase {
46+
public class SingleValueMatchQueryTests extends MapperServiceTestCase {
4747
interface Setup {
4848
XContentBuilder mapping(XContentBuilder builder) throws IOException;
4949

@@ -70,7 +70,7 @@ public static List<Object[]> params() {
7070

7171
private final Setup setup;
7272

73-
public SingleValueMathQueryTests(Setup setup) {
73+
public SingleValueMatchQueryTests(Setup setup) {
7474
this.setup = setup;
7575
}
7676

0 commit comments

Comments
 (0)