You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by cp...@apache.org on 2020/11/12 13:20:48 UTC
[lucene-solr] branch branch_8x updated: SOLR-14983: Fix response
returning original score instead of reranked score due to query and filter
combining. (Krishan Goyal, Jason Baik, Christine Poerschke)
This is an automated email from the ASF dual-hosted git repository.
cpoerschke pushed a commit to branch branch_8x
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git
The following commit(s) were added to refs/heads/branch_8x by this push:
new ad27dd7 SOLR-14983: Fix response returning original score instead of reranked score due to query and filter combining. (Krishan Goyal, Jason Baik, Christine Poerschke)
ad27dd7 is described below
commit ad27dd7c56e4f9e1d1828206e7595b557ed070cb
Author: Christine Poerschke <cp...@apache.org>
AuthorDate: Thu Nov 12 12:51:21 2020 +0000
SOLR-14983: Fix response returning original score instead of reranked score due to query and filter combining.
(Krishan Goyal, Jason Baik, Christine Poerschke)
---
solr/CHANGES.txt | 3 +
.../org/apache/solr/search/SolrIndexSearcher.java | 4 +-
.../apache/solr/search/SolrIndexSearcherTest.java | 123 +++++++++++++++++++++
3 files changed, 128 insertions(+), 2 deletions(-)
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index d1dbcbb..db4403c 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -40,6 +40,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
---------------------
diff --git a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
index ef78758..7000f5d 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
@@ -1602,7 +1602,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);
@@ -1711,7 +1711,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);
diff --git a/solr/core/src/test/org/apache/solr/search/SolrIndexSearcherTest.java b/solr/core/src/test/org/apache/solr/search/SolrIndexSearcherTest.java
index cb418e6..58b1901 100644
--- a/solr/core/src/test/org/apache/solr/search/SolrIndexSearcherTest.java
+++ b/solr/core/src/test/org/apache/solr/search/SolrIndexSearcherTest.java
@@ -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 -> {