diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 6b54d16c357..34c16c2d39d 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -211,6 +211,8 @@ Improvements * GITHUB#13156: Hunspell: don't proceed with other suggestions if we found good REP ones (Peter Gromov) +* GITHUB#13066: Support getMaxScore of DisjunctionSumScorer for non top level scoring clause (Shintaro Murakami) + Optimizations --------------------- diff --git a/lucene/core/src/java/org/apache/lucene/search/DisjunctionSumScorer.java b/lucene/core/src/java/org/apache/lucene/search/DisjunctionSumScorer.java index 6909af79ae5..26fbd19bcd6 100644 --- a/lucene/core/src/java/org/apache/lucene/search/DisjunctionSumScorer.java +++ b/lucene/core/src/java/org/apache/lucene/search/DisjunctionSumScorer.java @@ -18,10 +18,13 @@ package org.apache.lucene.search; import java.io.IOException; import java.util.List; +import org.apache.lucene.util.MathUtil; /** A Scorer for OR like queries, counterpart of ConjunctionScorer. */ final class DisjunctionSumScorer extends DisjunctionScorer { + private final List scorers; + /** * Construct a DisjunctionScorer. * @@ -31,6 +34,7 @@ final class DisjunctionSumScorer extends DisjunctionScorer { DisjunctionSumScorer(Weight weight, List subScorers, ScoreMode scoreMode) throws IOException { super(weight, subScorers, scoreMode); + this.scorers = subScorers; } @Override @@ -43,10 +47,25 @@ final class DisjunctionSumScorer extends DisjunctionScorer { return (float) score; } + @Override + public int advanceShallow(int target) throws IOException { + int min = DocIdSetIterator.NO_MORE_DOCS; + for (Scorer scorer : scorers) { + if (scorer.docID() <= target) { + min = Math.min(min, scorer.advanceShallow(target)); + } + } + return min; + } + @Override public float getMaxScore(int upTo) throws IOException { - // It's ok to return a bad upper bound here since we use WANDScorer when - // we actually care about block scores. - return Float.MAX_VALUE; + double maxScore = 0; + for (Scorer scorer : scorers) { + if (scorer.docID() <= upTo) { + maxScore += scorer.getMaxScore(upTo); + } + } + return (float) MathUtil.sumUpperBound(maxScore, scorers.size()); } } diff --git a/lucene/core/src/test/org/apache/lucene/search/TestBoolean2ScorerSupplier.java b/lucene/core/src/test/org/apache/lucene/search/TestBoolean2ScorerSupplier.java index 660a820b2d0..c9c9775e449 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestBoolean2ScorerSupplier.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestBoolean2ScorerSupplier.java @@ -536,5 +536,16 @@ public class TestBoolean2ScorerSupplier extends LuceneTestCase { Scorer scorer = new Boolean2ScorerSupplier(new FakeWeight(), subs, ScoreMode.TOP_SCORES, 0).get(10); assertEquals(2.0, scorer.getMaxScore(DocIdSetIterator.NO_MORE_DOCS), 0.0); + + subs = new EnumMap<>(Occur.class); + for (Occur occur : Occur.values()) { + subs.put(occur, new ArrayList<>()); + } + + subs.get(Occur.SHOULD).add(clause1); + subs.get(Occur.SHOULD).add(clause2); + + scorer = new Boolean2ScorerSupplier(new FakeWeight(), subs, ScoreMode.TOP_SCORES, 0).get(10); + assertEquals(2.0, scorer.getMaxScore(DocIdSetIterator.NO_MORE_DOCS), 0.0); } }