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);
}
}