LUCENE-7833: Fix score computation with ToParentBlockJoinQuery and ScoreMode.MAX.

This commit is contained in:
Adrien Grand 2017-05-19 08:28:37 +02:00
parent eb475db9c4
commit 3bb4662e63
3 changed files with 64 additions and 3 deletions

View File

@ -147,6 +147,9 @@ Bug Fixes
* LUCENE-7831: CodecUtil should not seek to negative offsets. (Adrien Grand) * 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 Improvements
* LUCENE-7782: OfflineSorter now passes the total number of items it * LUCENE-7782: OfflineSorter now passes the total number of items it

View File

@ -312,7 +312,7 @@ public class ToParentBlockJoinQuery extends Query {
score = Math.min(score, childScore); score = Math.min(score, childScore);
break; break;
case Max: case Max:
score = Math.min(score, childScore); score = Math.max(score, childScore);
break; break;
case None: case None:
break; break;

View File

@ -52,6 +52,9 @@ import org.apache.lucene.index.ReaderUtil;
import org.apache.lucene.index.Term; import org.apache.lucene.index.Term;
import org.apache.lucene.search.*; import org.apache.lucene.search.*;
import org.apache.lucene.search.BooleanClause.Occur; 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.store.Directory;
import org.apache.lucene.util.BitSet; import org.apache.lucene.util.BitSet;
import org.apache.lucene.util.Bits; import org.apache.lucene.util.Bits;
@ -1472,5 +1475,60 @@ public class TestBlockJoin extends LuceneTestCase {
dir.close(); 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();
}
} }