mirror of https://github.com/apache/lucene.git
LUCENE-9393: FunctionScoreQuery turns TOP_DOCS to COMPLETE in inner weights (#1553)
FunctionScoreQuery can't really use WAND algorithm even if TOP_DOCS score mode is requested. This commit makes the inner weight created use COMPLETE
This commit is contained in:
parent
b055c7489f
commit
e1a97a0f1e
|
@ -200,6 +200,8 @@ Improvements
|
|||
|
||||
* LUCENE-9359: SegmentInfos#readCommit now always returns a
|
||||
CorruptIndexException if the content of the file is invalid. (Adrien Grand)
|
||||
|
||||
* LUCENE-9393: FunctionScoreQuery turns TOP_DOCS to COMPLETE in inner weights
|
||||
|
||||
Optimizations
|
||||
---------------------
|
||||
|
|
|
@ -105,7 +105,13 @@ public final class FunctionScoreQuery extends Query {
|
|||
|
||||
@Override
|
||||
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
|
||||
Weight inner = in.createWeight(searcher, scoreMode.needsScores() && source.needsScores() ? scoreMode : ScoreMode.COMPLETE_NO_SCORES, 1f);
|
||||
ScoreMode sm;
|
||||
if (scoreMode.needsScores() && source.needsScores()) {
|
||||
sm = ScoreMode.COMPLETE;
|
||||
} else {
|
||||
sm = ScoreMode.COMPLETE_NO_SCORES;
|
||||
}
|
||||
Weight inner = in.createWeight(searcher, sm, 1f);
|
||||
if (scoreMode.needsScores() == false)
|
||||
return inner;
|
||||
return new FunctionScoreWeight(this, inner, source.rewrite(searcher), boost);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
package org.apache.lucene.queries.function;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.document.NumericDocValuesField;
|
||||
|
@ -37,8 +38,10 @@ import org.apache.lucene.search.IndexSearcher;
|
|||
import org.apache.lucene.search.MatchAllDocsQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.QueryUtils;
|
||||
import org.apache.lucene.search.ScoreMode;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.apache.lucene.search.TopDocs;
|
||||
import org.apache.lucene.search.Weight;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
|
@ -244,4 +247,33 @@ public class TestFunctionScoreQuery extends FunctionTestSetup {
|
|||
|
||||
}
|
||||
|
||||
public void testScoreMode() throws Exception {
|
||||
// Value Source doesn't need scores
|
||||
assertInnerScoreMode(ScoreMode.COMPLETE_NO_SCORES, ScoreMode.COMPLETE, DoubleValuesSource.fromDoubleField("foo"));
|
||||
assertInnerScoreMode(ScoreMode.COMPLETE_NO_SCORES, ScoreMode.COMPLETE_NO_SCORES, DoubleValuesSource.fromDoubleField("foo"));
|
||||
assertInnerScoreMode(ScoreMode.COMPLETE_NO_SCORES, ScoreMode.TOP_SCORES, DoubleValuesSource.fromDoubleField("foo"));
|
||||
|
||||
// Value Source needs scores
|
||||
assertInnerScoreMode(ScoreMode.COMPLETE, ScoreMode.COMPLETE, DoubleValuesSource.SCORES);
|
||||
assertInnerScoreMode(ScoreMode.COMPLETE_NO_SCORES, ScoreMode.COMPLETE_NO_SCORES, DoubleValuesSource.SCORES);
|
||||
assertInnerScoreMode(ScoreMode.COMPLETE, ScoreMode.TOP_SCORES, DoubleValuesSource.SCORES);
|
||||
|
||||
}
|
||||
|
||||
private void assertInnerScoreMode(ScoreMode expectedScoreMode, ScoreMode inputScoreMode, DoubleValuesSource valueSource) throws IOException {
|
||||
final AtomicReference<ScoreMode> scoreModeInWeight = new AtomicReference<ScoreMode>();
|
||||
Query innerQ = new TermQuery(new Term(TEXT_FIELD, "a")) {
|
||||
|
||||
@Override
|
||||
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
|
||||
scoreModeInWeight.set(scoreMode);
|
||||
return super.createWeight(searcher, scoreMode, boost);
|
||||
}
|
||||
};
|
||||
|
||||
FunctionScoreQuery fq = new FunctionScoreQuery(innerQ, valueSource);
|
||||
fq.createWeight(searcher, inputScoreMode, 1f);
|
||||
assertEquals(expectedScoreMode, scoreModeInWeight.get());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue