diff --git a/docs/changelog/120133.yaml b/docs/changelog/120133.yaml new file mode 100644 index 000000000000..4ec88267a1bf --- /dev/null +++ b/docs/changelog/120133.yaml @@ -0,0 +1,6 @@ +pr: 120133 +summary: Use approximation to advance matched queries +area: Search +type: bug +issues: + - 120130 diff --git a/server/src/main/java/org/elasticsearch/search/fetch/subphase/MatchedQueriesPhase.java b/server/src/main/java/org/elasticsearch/search/fetch/subphase/MatchedQueriesPhase.java index 5220dadec7a1..53116ff8f6eb 100644 --- a/server/src/main/java/org/elasticsearch/search/fetch/subphase/MatchedQueriesPhase.java +++ b/server/src/main/java/org/elasticsearch/search/fetch/subphase/MatchedQueriesPhase.java @@ -9,10 +9,12 @@ package org.elasticsearch.search.fetch.subphase; import org.apache.lucene.index.LeafReaderContext; +import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.search.Query; import org.apache.lucene.search.ScoreMode; import org.apache.lucene.search.Scorer; import org.apache.lucene.search.ScorerSupplier; +import org.apache.lucene.search.TwoPhaseIterator; import org.apache.lucene.search.Weight; import org.elasticsearch.index.query.ParsedQuery; import org.elasticsearch.search.fetch.FetchContext; @@ -52,8 +54,9 @@ public FetchSubPhaseProcessor getProcessor(FetchContext context) throws IOExcept ); } return new FetchSubPhaseProcessor() { + record ScorerAndIterator(Scorer scorer, DocIdSetIterator approximation, TwoPhaseIterator twoPhase) {} - final Map matchingIterators = new HashMap<>(); + final Map matchingIterators = new HashMap<>(); @Override public void setNextReader(LeafReaderContext readerContext) throws IOException { @@ -63,7 +66,14 @@ public void setNextReader(LeafReaderContext readerContext) throws IOException { if (ss != null) { Scorer scorer = ss.get(0L); if (scorer != null) { - matchingIterators.put(entry.getKey(), scorer); + final TwoPhaseIterator twoPhase = scorer.twoPhaseIterator(); + final DocIdSetIterator iterator; + if (twoPhase == null) { + iterator = scorer.iterator(); + } else { + iterator = twoPhase.approximation(); + } + matchingIterators.put(entry.getKey(), new ScorerAndIterator(scorer, iterator, twoPhase)); } } } @@ -73,13 +83,13 @@ public void setNextReader(LeafReaderContext readerContext) throws IOException { public void process(HitContext hitContext) throws IOException { Map matches = new LinkedHashMap<>(); int doc = hitContext.docId(); - for (Map.Entry entry : matchingIterators.entrySet()) { - Scorer scorer = entry.getValue(); - if (scorer.iterator().docID() < doc) { - scorer.iterator().advance(doc); + for (Map.Entry entry : matchingIterators.entrySet()) { + ScorerAndIterator query = entry.getValue(); + if (query.approximation.docID() < doc) { + query.approximation.advance(doc); } - if (scorer.iterator().docID() == doc) { - matches.put(entry.getKey(), scorer.score()); + if (query.approximation.docID() == doc && (query.twoPhase == null || query.twoPhase.matches())) { + matches.put(entry.getKey(), query.scorer.score()); } } hitContext.hit().matchedQueries(matches);