diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index a5693f07b51..9a29b7b93d1 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -32,6 +32,9 @@ Bug Fixes * LUCENE-7476: JapaneseNumberFilter should not invoke incrementToken on its input after it's exhausted (Andy Hind via Mike McCandless) +* LUCENE-7486: DisjunctionMaxQuery does not work correctly with queries that + return negative scores. (Ivan Provalov, Uwe Schindler, Adrien Grand) + Improvements * LUCENE-7439: FuzzyQuery now matches all terms within the specified diff --git a/lucene/core/src/java/org/apache/lucene/search/DisjunctionMaxScorer.java b/lucene/core/src/java/org/apache/lucene/search/DisjunctionMaxScorer.java index 3d6fbdaf1bf..2356f5e817e 100644 --- a/lucene/core/src/java/org/apache/lucene/search/DisjunctionMaxScorer.java +++ b/lucene/core/src/java/org/apache/lucene/search/DisjunctionMaxScorer.java @@ -48,7 +48,7 @@ final class DisjunctionMaxScorer extends DisjunctionScorer { @Override protected float score(DisiWrapper topList) throws IOException { float scoreSum = 0; - float scoreMax = 0; + float scoreMax = Float.NEGATIVE_INFINITY; for (DisiWrapper w = topList; w != null; w = w.next) { final float subScore = w.scorer.score(); scoreSum += subScore; diff --git a/lucene/core/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java b/lucene/core/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java index 79c32d38bc9..87046c7ba19 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java @@ -509,6 +509,22 @@ public class TestDisjunctionMaxQuery extends LuceneTestCase { directory.close(); } + public void testNegativeScore() throws Exception { + DisjunctionMaxQuery q = new DisjunctionMaxQuery( + Arrays.asList( + new BoostQuery(tq("hed", "albino"), -1f), + new BoostQuery(tq("hed", "elephant"), -1f) + ), 0.0f); + + ScoreDoc[] h = s.search(q, 1000).scoreDocs; + + assertEquals("all docs should match " + q.toString(), 4, h.length); + + for (int i = 0; i < h.length; i++) { + assertTrue("score should be negative", h[i].score < 0); + } + } + /** macro */ protected Query tq(String f, String t) { return new TermQuery(new Term(f, t));