From 3bb4662e63484eb032e6c1e1a175999869ddff88 Mon Sep 17 00:00:00 2001 From: Adrien Grand Date: Fri, 19 May 2017 08:28:37 +0200 Subject: [PATCH] LUCENE-7833: Fix score computation with ToParentBlockJoinQuery and ScoreMode.MAX. --- lucene/CHANGES.txt | 3 + .../search/join/ToParentBlockJoinQuery.java | 2 +- .../lucene/search/join/TestBlockJoin.java | 62 ++++++++++++++++++- 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index f309334b41d..43b13b17ddd 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -147,6 +147,9 @@ Bug Fixes * LUCENE-7831: CodecUtil should not seek to negative offsets. (Adrien Grand) +* LUCENE-7833: ToParentBlockJoinQuery computed the min score instead of the max + score with ScoreMode.MAX. (Adrien Grand) + Improvements * LUCENE-7782: OfflineSorter now passes the total number of items it diff --git a/lucene/join/src/java/org/apache/lucene/search/join/ToParentBlockJoinQuery.java b/lucene/join/src/java/org/apache/lucene/search/join/ToParentBlockJoinQuery.java index 0f1f7270367..1b6f3864253 100644 --- a/lucene/join/src/java/org/apache/lucene/search/join/ToParentBlockJoinQuery.java +++ b/lucene/join/src/java/org/apache/lucene/search/join/ToParentBlockJoinQuery.java @@ -312,7 +312,7 @@ public class ToParentBlockJoinQuery extends Query { score = Math.min(score, childScore); break; case Max: - score = Math.min(score, childScore); + score = Math.max(score, childScore); break; case None: break; diff --git a/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java b/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java index da3c20ed578..c87fdbb6ce5 100644 --- a/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java +++ b/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java @@ -52,6 +52,9 @@ import org.apache.lucene.index.ReaderUtil; import org.apache.lucene.index.Term; import org.apache.lucene.search.*; import org.apache.lucene.search.BooleanClause.Occur; +import org.apache.lucene.search.similarities.BasicStats; +import org.apache.lucene.search.similarities.Similarity; +import org.apache.lucene.search.similarities.SimilarityBase; import org.apache.lucene.store.Directory; import org.apache.lucene.util.BitSet; import org.apache.lucene.util.Bits; @@ -230,11 +233,11 @@ public class TestBlockJoin extends LuceneTestCase { matchingChildren = s.search(childrenQuery, 1); assertEquals(1, matchingChildren.totalHits); assertEquals("java", s.doc(matchingChildren.scoreDocs[0].doc).get("skill")); - + r.close(); dir.close(); } - + public void testSimple() throws Exception { final Directory dir = newDirectory(); @@ -1472,5 +1475,60 @@ public class TestBlockJoin extends LuceneTestCase { dir.close(); } + public void testScoreMode() throws IOException { + Similarity sim = new SimilarityBase() { + + @Override + public String toString() { + return "TestSim"; + } + + @Override + protected float score(BasicStats stats, float freq, float docLen) { + return freq; + } + }; + Directory dir = newDirectory(); + RandomIndexWriter w = new RandomIndexWriter(random(), dir, newIndexWriterConfig().setSimilarity(sim)); + w.addDocuments(Arrays.asList( + Collections.singleton(newTextField("foo", "bar bar", Store.NO)), + Collections.singleton(newTextField("foo", "bar", Store.NO)), + Collections.emptyList(), + Collections.singleton(newStringField("type", new BytesRef("parent"), Store.NO)))); + DirectoryReader reader = w.getReader(); + w.close(); + IndexSearcher searcher = newSearcher(reader); + searcher.setSimilarity(sim); + BitSetProducer parents = new QueryBitSetProducer(new TermQuery(new Term("type", "parent"))); + for (ScoreMode scoreMode : ScoreMode.values()) { + Query query = new ToParentBlockJoinQuery(new TermQuery(new Term("foo", "bar")), parents, scoreMode); + TopDocs topDocs = searcher.search(query, 10); + assertEquals(1, topDocs.totalHits); + assertEquals(3, topDocs.scoreDocs[0].doc); + float expectedScore; + switch (scoreMode) { + case Avg: + expectedScore = 1.5f; + break; + case Max: + expectedScore = 2f; + break; + case Min: + expectedScore = 1f; + break; + case None: + expectedScore = 0f; + break; + case Total: + expectedScore = 3f; + break; + default: + throw new AssertionError(); + } + assertEquals(expectedScore, topDocs.scoreDocs[0].score, 0f); + } + reader.close(); + dir.close(); + } }