mirror of https://github.com/apache/lucene.git
SOLR-14983: Fix response returning original score instead of reranked score due to query and filter combining.
(Krishan Goyal, Jason Baik, Christine Poerschke)
This commit is contained in:
parent
66e285e7ae
commit
2f02040a4c
|
@ -194,6 +194,9 @@ Bug Fixes
|
|||
|
||||
* SOLR-14971: AtomicUpdate 'remove', 'add-distinct' operations now works on numeric, date fields in uncommitted docs (Jason Gerlowski)
|
||||
|
||||
* SOLR-14983: Fix response returning original score instead of reranked score due to query and filter combining.
|
||||
(Krishan Goyal, Jason Baik, Christine Poerschke)
|
||||
|
||||
Other Changes
|
||||
---------------------
|
||||
|
||||
|
|
|
@ -1605,7 +1605,7 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
|
|||
} else {
|
||||
hitsRelation = topDocs.totalHits.relation;
|
||||
}
|
||||
if (cmd.getSort() != null && query instanceof RankQuery == false && (cmd.getFlags() & GET_SCORES) != 0) {
|
||||
if (cmd.getSort() != null && cmd.getQuery() instanceof RankQuery == false && (cmd.getFlags() & GET_SCORES) != 0) {
|
||||
TopFieldCollector.populateScores(topDocs.scoreDocs, this, query);
|
||||
}
|
||||
populateNextCursorMarkFromTopDocs(qr, cmd, topDocs);
|
||||
|
@ -1714,7 +1714,7 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
|
|||
assert (totalHits == set.size()) || qr.isPartialResults();
|
||||
|
||||
TopDocs topDocs = topCollector.topDocs(0, len);
|
||||
if (cmd.getSort() != null && query instanceof RankQuery == false && (cmd.getFlags() & GET_SCORES) != 0) {
|
||||
if (cmd.getSort() != null && cmd.getQuery() instanceof RankQuery == false && (cmd.getFlags() & GET_SCORES) != 0) {
|
||||
TopFieldCollector.populateScores(topDocs.scoreDocs, this, query);
|
||||
}
|
||||
populateNextCursorMarkFromTopDocs(qr, cmd, topDocs);
|
||||
|
|
|
@ -19,12 +19,21 @@ package org.apache.solr.search;
|
|||
import java.io.IOException;
|
||||
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.Explanation;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.QueryVisitor;
|
||||
import org.apache.lucene.search.Rescorer;
|
||||
import org.apache.lucene.search.ScoreDoc;
|
||||
import org.apache.lucene.search.ScoreMode;
|
||||
import org.apache.lucene.search.Sort;
|
||||
import org.apache.lucene.search.SortField;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.apache.lucene.search.TopDocs;
|
||||
import org.apache.lucene.search.TopDocsCollector;
|
||||
import org.apache.lucene.search.TotalHits;
|
||||
import org.apache.lucene.search.Weight;
|
||||
import org.apache.solr.handler.component.MergeStrategy;
|
||||
import org.apache.solr.SolrTestCaseJ4;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
|
@ -187,6 +196,120 @@ public class SolrIndexSearcherTest extends SolrTestCaseJ4 {
|
|||
});
|
||||
}
|
||||
|
||||
public void testReranking() throws Exception {
|
||||
float fixedScore = 1.23f;
|
||||
for (boolean doFilter : new boolean[]{ false, true }) {
|
||||
for (boolean doSort : new boolean[]{ false, true }) {
|
||||
for (int getDocSetFlag : new int[]{ 0, SolrIndexSearcher.GET_DOCSET }) {
|
||||
implTestReranking(doFilter, doSort, getDocSetFlag, null); // don't fix score i.e. no re-ranking
|
||||
implTestReranking(doFilter, doSort, getDocSetFlag, fixedScore); // fix score to be non-zero and non-one
|
||||
fixedScore *= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void implTestReranking(boolean doFilter, boolean doSort, int getDocSetFlag, Float fixedScore) throws Exception {
|
||||
h.getCore().withSearcher(searcher -> {
|
||||
|
||||
final QueryCommand cmd = new QueryCommand();
|
||||
cmd.setFlags(SolrIndexSearcher.GET_SCORES | getDocSetFlag);
|
||||
|
||||
if (doSort) {
|
||||
cmd.setSort(new Sort(SortField.FIELD_SCORE, new SortField("id", SortField.Type.STRING)));
|
||||
}
|
||||
|
||||
if (doFilter) {
|
||||
cmd.setFilterList(new TermQuery(new Term("field4_t", Integer.toString(NUM_DOCS - 1))));
|
||||
}
|
||||
|
||||
cmd.setQuery(new TermQuery(new Term("field1_s", "foo")));
|
||||
|
||||
final float expectedScore;
|
||||
if (fixedScore == null) {
|
||||
expectedScore = 1f;
|
||||
} else {
|
||||
expectedScore = fixedScore.floatValue();
|
||||
cmd.setQuery(new FixedScoreReRankQuery(cmd.getQuery(), expectedScore));
|
||||
}
|
||||
|
||||
final QueryResult qr = new QueryResult();
|
||||
searcher.search(qr, cmd);
|
||||
|
||||
// check score for the first document
|
||||
final DocIterator iter = qr.getDocList().iterator();
|
||||
iter.next();
|
||||
assertEquals(expectedScore, iter.score(), 0);
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private static final class FixedScoreReRankQuery extends RankQuery {
|
||||
|
||||
private Query q;
|
||||
final private float fixedScore;
|
||||
|
||||
public FixedScoreReRankQuery(Query q, float fixedScore) {
|
||||
this.q = q;
|
||||
this.fixedScore = fixedScore;
|
||||
}
|
||||
|
||||
public Weight createWeight(IndexSearcher indexSearcher, ScoreMode scoreMode, float boost) throws IOException {
|
||||
return q.createWeight(indexSearcher, scoreMode, boost);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(QueryVisitor visitor) {
|
||||
q.visit(visitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return this == obj;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return q.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(String field) {
|
||||
return q.toString(field);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"rawtypes"})
|
||||
public TopDocsCollector getTopDocsCollector(int len, QueryCommand cmd, IndexSearcher searcher) throws IOException {
|
||||
return new ReRankCollector(len, len, new Rescorer() {
|
||||
@Override
|
||||
public TopDocs rescore(IndexSearcher searcher, TopDocs firstPassTopDocs, int topN) {
|
||||
for (ScoreDoc scoreDoc : firstPassTopDocs.scoreDocs) {
|
||||
scoreDoc.score = fixedScore;
|
||||
}
|
||||
return firstPassTopDocs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Explanation explain(IndexSearcher searcher, Explanation firstPassExplanation, int docID) {
|
||||
return firstPassExplanation;
|
||||
}
|
||||
}, cmd, searcher, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MergeStrategy getMergeStrategy() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public RankQuery wrap(Query q) {
|
||||
this.q = q;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public void testMinExactWithFilters() throws Exception {
|
||||
|
||||
h.getCore().withSearcher(searcher -> {
|
||||
|
|
Loading…
Reference in New Issue