Fix a bug in function_score queries where we use the wrong boost_mode. (#35148)

This commit is contained in:
Julie Tibshirani 2018-11-01 11:15:26 -07:00 committed by GitHub
parent 0bdf6a768a
commit 8fb3290e5c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 9 deletions

View File

@ -123,8 +123,7 @@ public class FunctionScoreQuery extends Query {
final ScoreMode scoreMode; final ScoreMode scoreMode;
final float maxBoost; final float maxBoost;
private final Float minScore; private final Float minScore;
private final CombineFunction combineFunction;
protected final CombineFunction combineFunction;
/** /**
* Creates a FunctionScoreQuery without function. * Creates a FunctionScoreQuery without function.
@ -192,6 +191,10 @@ public class FunctionScoreQuery extends Query {
return minScore; return minScore;
} }
public CombineFunction getCombineFunction() {
return combineFunction;
}
@Override @Override
public Query rewrite(IndexReader reader) throws IOException { public Query rewrite(IndexReader reader) throws IOException {
Query rewritten = super.rewrite(reader); Query rewritten = super.rewrite(reader);

View File

@ -309,18 +309,14 @@ public class FunctionScoreQueryBuilder extends AbstractQueryBuilder<FunctionScor
query = new MatchAllDocsQuery(); query = new MatchAllDocsQuery();
} }
CombineFunction boostMode = this.boostMode == null ? DEFAULT_BOOST_MODE : this.boostMode;
// handle cases where only one score function and no filter was provided. In this case we create a FunctionScoreQuery. // handle cases where only one score function and no filter was provided. In this case we create a FunctionScoreQuery.
if (filterFunctions.length == 0) { if (filterFunctions.length == 0) {
return new FunctionScoreQuery(query, minScore, maxBoost); return new FunctionScoreQuery(query, minScore, maxBoost);
} else if (filterFunctions.length == 1 && filterFunctions[0] instanceof FunctionScoreQuery.FilterScoreFunction == false) { } else if (filterFunctions.length == 1 && filterFunctions[0] instanceof FunctionScoreQuery.FilterScoreFunction == false) {
CombineFunction combineFunction = this.boostMode; return new FunctionScoreQuery(query, filterFunctions[0], boostMode, minScore, maxBoost);
if (combineFunction == null) {
combineFunction = filterFunctions[0].getDefaultScoreCombiner();
}
return new FunctionScoreQuery(query, filterFunctions[0], combineFunction, minScore, maxBoost);
} }
// in all other cases we create a FunctionScoreQuery with filters // in all other cases we create a FunctionScoreQuery with filters
CombineFunction boostMode = this.boostMode == null ? DEFAULT_BOOST_MODE : this.boostMode;
return new FunctionScoreQuery(query, scoreMode, filterFunctions, boostMode, minScore, maxBoost); return new FunctionScoreQuery(query, scoreMode, filterFunctions, boostMode, minScore, maxBoost);
} }

View File

@ -20,7 +20,6 @@
package org.elasticsearch.index.query.functionscore; package org.elasticsearch.index.query.functionscore;
import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonParseException;
import org.apache.lucene.index.Term; import org.apache.lucene.index.Term;
import org.apache.lucene.search.MatchAllDocsQuery; import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
@ -672,6 +671,29 @@ public class FunctionScoreQueryBuilderTests extends AbstractQueryTestCase<Functi
assertSame(rewrite.filterFunctionBuilders()[1].getFilter(), secondFunction); assertSame(rewrite.filterFunctionBuilders()[1].getFilter(), secondFunction);
} }
/**
* Please see https://github.com/elastic/elasticsearch/issues/35123 for context.
*/
public void testSingleScriptFunction() throws IOException {
QueryBuilder queryBuilder = RandomQueryBuilder.createQuery(random());
ScoreFunctionBuilder functionBuilder = new ScriptScoreFunctionBuilder(
new Script(ScriptType.INLINE, MockScriptEngine.NAME, "1", Collections.emptyMap()));
FunctionScoreQueryBuilder builder = functionScoreQuery(queryBuilder, functionBuilder);
if (randomBoolean()) {
builder.boostMode(randomFrom(CombineFunction.values()));
}
Query query = builder.toQuery(createShardContext());
assertThat(query, instanceOf(FunctionScoreQuery.class));
CombineFunction expectedBoostMode = builder.boostMode() != null
? builder.boostMode()
: FunctionScoreQueryBuilder.DEFAULT_BOOST_MODE;
CombineFunction actualBoostMode = ((FunctionScoreQuery) query).getCombineFunction();
assertEquals(expectedBoostMode, actualBoostMode);
}
public void testQueryMalformedArrayNotSupported() throws IOException { public void testQueryMalformedArrayNotSupported() throws IOException {
String json = String json =
"{\n" + "{\n" +