Function score query: remove deprecated support for boost_factor

boost_factor was deprecated in 1.4.0.beta1. We can remove the support for it in 3.0, its replacement is `weight`.

Closes #13510
This commit is contained in:
javanna 2015-09-11 12:00:10 +02:00 committed by Luca Cavanna
parent df9d4eca66
commit a641c7ae52
13 changed files with 27 additions and 307 deletions

View File

@ -1,70 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.common.lucene.search.function;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.search.Explanation;
/**
*
*/
@Deprecated
public class BoostScoreFunction extends ScoreFunction {
public static final String BOOST_WEIGHT_ERROR_MESSAGE = "'boost_factor' and 'weight' cannot be used together. Use 'weight'.";
private final float boost;
public BoostScoreFunction(float boost) {
super(CombineFunction.MULT);
this.boost = boost;
}
public float getBoost() {
return boost;
}
@Override
public LeafScoreFunction getLeafScoreFunction(LeafReaderContext ctx) {
return new LeafScoreFunction() {
@Override
public double score(int docId, float subQueryScore) {
return boost;
}
@Override
public Explanation explainScore(int docId, Explanation subQueryScore) {
return Explanation.match(boost, "static boost factor", Explanation.match(boost, "boostFactor"));
}
};
}
@Override
public boolean needsScores() {
return false;
}
@Override
public String toString() {
return "boost[" + boost + "]";
}
}

View File

@ -35,9 +35,6 @@ public class WeightFactorFunction extends ScoreFunction {
public WeightFactorFunction(float weight, ScoreFunction scoreFunction) {
super(CombineFunction.MULT);
if (scoreFunction instanceof BoostScoreFunction) {
throw new IllegalArgumentException(BoostScoreFunction.BOOST_WEIGHT_ERROR_MESSAGE);
}
if (scoreFunction == null) {
this.scoreFunction = SCORE_ONE;
} else {

View File

@ -89,8 +89,7 @@ import java.util.Locale;
* <p>
* See {@link GaussDecayFunctionBuilder} and {@link GaussDecayFunctionParser}
* for an example. The parser furthermore needs to be registered in the
* {@link org.elasticsearch.index.query.functionscore.FunctionScoreModule
* FunctionScoreModule}.
* {@link org.elasticsearch.search.SearchModule SearchModule}.
*
* **/

View File

@ -21,7 +21,6 @@ package org.elasticsearch.index.query.functionscore;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.ConstantScoreQuery;
@ -31,20 +30,14 @@ import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.lucene.search.Queries;
import org.elasticsearch.common.lucene.search.function.CombineFunction;
import org.elasticsearch.common.lucene.search.function.FiltersFunctionScoreQuery;
import org.elasticsearch.common.lucene.search.function.FunctionScoreQuery;
import org.elasticsearch.common.lucene.search.function.ScoreFunction;
import org.elasticsearch.common.lucene.search.function.WeightFactorFunction;
import org.elasticsearch.common.lucene.search.function.*;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.index.query.QueryParser;
import org.elasticsearch.index.query.QueryParsingException;
import org.elasticsearch.index.query.functionscore.factor.FactorParser;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
/**
*
@ -55,7 +48,6 @@ public class FunctionScoreQueryParser implements QueryParser {
// For better readability of error message
static final String MISPLACED_FUNCTION_MESSAGE_PREFIX = "you can either define [functions] array or a single function, not both. ";
static final String MISPLACED_BOOST_FUNCTION_MESSAGE_SUFFIX = " did you mean [boost] instead?";
public static final ParseField WEIGHT_FIELD = new ParseField("weight");
private static final ParseField FILTER_FIELD = new ParseField("filter").withAllDeprecated("query");
@ -124,7 +116,7 @@ public class FunctionScoreQueryParser implements QueryParser {
} else if ("functions".equals(currentFieldName)) {
if (singleFunctionFound) {
String errorString = "already found [" + singleFunctionName + "], now encountering [functions].";
handleMisplacedFunctionsDeclaration(errorString, singleFunctionName);
handleMisplacedFunctionsDeclaration(errorString);
}
currentFieldName = parseFiltersAndFunctions(parseContext, parser, filterFunctions, currentFieldName);
functionArrayFound = true;
@ -141,7 +133,7 @@ public class FunctionScoreQueryParser implements QueryParser {
}
if (functionArrayFound) {
String errorString = "already found [functions] array, now encountering [" + currentFieldName + "].";
handleMisplacedFunctionsDeclaration(errorString, currentFieldName);
handleMisplacedFunctionsDeclaration(errorString);
}
if (filterFunctions.size() > 0) {
throw new ElasticsearchParseException("failed to parse [{}] query. already found function [{}], now encountering [{}]. use [functions] array if you want to define several functions.", NAME, singleFunctionName, currentFieldName);
@ -191,12 +183,8 @@ public class FunctionScoreQueryParser implements QueryParser {
}
}
private void handleMisplacedFunctionsDeclaration(String errorString, String functionName) {
errorString = MISPLACED_FUNCTION_MESSAGE_PREFIX + errorString;
if (Arrays.asList(FactorParser.NAMES).contains(functionName)) {
errorString = errorString + MISPLACED_BOOST_FUNCTION_MESSAGE_SUFFIX;
}
throw new ElasticsearchParseException("failed to parse [{}] query. [{}]", NAME, errorString);
private void handleMisplacedFunctionsDeclaration(String errorString) {
throw new ElasticsearchParseException("failed to parse [{}] query. [{}]", NAME, MISPLACED_FUNCTION_MESSAGE_PREFIX + errorString);
}
private String parseFiltersAndFunctions(QueryParseContext parseContext, XContentParser parser,

View File

@ -20,7 +20,6 @@
package org.elasticsearch.index.query.functionscore;
import org.elasticsearch.index.query.functionscore.exp.ExponentialDecayFunctionBuilder;
import org.elasticsearch.index.query.functionscore.factor.FactorBuilder;
import org.elasticsearch.index.query.functionscore.fieldvaluefactor.FieldValueFactorFunctionBuilder;
import org.elasticsearch.index.query.functionscore.gauss.GaussDecayFunctionBuilder;
import org.elasticsearch.index.query.functionscore.lin.LinearDecayFunctionBuilder;
@ -29,8 +28,6 @@ import org.elasticsearch.index.query.functionscore.script.ScriptScoreFunctionBui
import org.elasticsearch.index.query.functionscore.weight.WeightBuilder;
import org.elasticsearch.script.Script;
import java.util.Map;
public class ScoreFunctionBuilders {
public static ExponentialDecayFunctionBuilder exponentialDecayFunction(String fieldName, Object origin, Object scale) {

View File

@ -23,7 +23,6 @@ import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.index.query.QueryParsingException;
import org.elasticsearch.index.query.functionscore.exp.ExponentialDecayFunctionParser;
import org.elasticsearch.index.query.functionscore.factor.FactorParser;
import org.elasticsearch.index.query.functionscore.fieldvaluefactor.FieldValueFactorFunctionParser;
import org.elasticsearch.index.query.functionscore.gauss.GaussDecayFunctionParser;
import org.elasticsearch.index.query.functionscore.lin.LinearDecayFunctionParser;
@ -42,8 +41,7 @@ public class ScoreFunctionParserMapper {
@Inject
public ScoreFunctionParserMapper(Set<ScoreFunctionParser> parsers) {
Map<String, ScoreFunctionParser> map = new HashMap<>();
// build-in parsers
addParser(new FactorParser(), map);
// built-in parsers
addParser(new ScriptScoreFunctionParser(), map);
addParser(new GaussDecayFunctionParser(), map);
addParser(new LinearDecayFunctionParser(), map);

View File

@ -1,67 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.index.query.functionscore.factor;
import org.elasticsearch.common.lucene.search.function.BoostScoreFunction;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilder;
import java.io.IOException;
/**
* A query that simply applies the boost factor to another query (multiply it).
*
*
*/
@Deprecated
public class FactorBuilder extends ScoreFunctionBuilder {
private Float boostFactor;
/**
* Sets the boost factor for this query.
*/
public FactorBuilder boostFactor(float boost) {
this.boostFactor = new Float(boost);
return this;
}
@Override
public void doXContent(XContentBuilder builder, Params params) throws IOException {
if (boostFactor != null) {
builder.field("boost_factor", boostFactor.floatValue());
}
}
@Override
public String getName() {
return FactorParser.NAMES[0];
}
@Override
public ScoreFunctionBuilder setWeight(float weight) {
throw new IllegalArgumentException(BoostScoreFunction.BOOST_WEIGHT_ERROR_MESSAGE);
}
@Override
public void buildWeight(XContentBuilder builder) throws IOException {
//we do not want the weight to be written for boost_factor as it does not make sense to have it
}
}

View File

@ -1,55 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.index.query.functionscore.factor;
import org.elasticsearch.index.query.functionscore.ScoreFunctionParser;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.lucene.search.function.BoostScoreFunction;
import org.elasticsearch.common.lucene.search.function.ScoreFunction;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.index.query.QueryParsingException;
import java.io.IOException;
/**
*
*/
@Deprecated
public class FactorParser implements ScoreFunctionParser {
public static String[] NAMES = { "boost_factor", "boostFactor" };
@Inject
public FactorParser() {
}
@Override
public ScoreFunction parse(QueryParseContext parseContext, XContentParser parser) throws IOException, QueryParsingException {
float boostFactor = parser.floatValue();
return new BoostScoreFunction(boostFactor);
}
@Override
public String[] getNames() {
return NAMES;
}
}

View File

@ -20,12 +20,7 @@
package org.elasticsearch.search.internal;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Collector;
import org.apache.lucene.search.ConstantScoreQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.*;
import org.apache.lucene.util.Counter;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.cache.recycler.PageCacheRecycler;
@ -33,8 +28,8 @@ import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.lease.Releasables;
import org.elasticsearch.common.lucene.search.Queries;
import org.elasticsearch.common.lucene.search.function.BoostScoreFunction;
import org.elasticsearch.common.lucene.search.function.FunctionScoreQuery;
import org.elasticsearch.common.lucene.search.function.WeightFactorFunction;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.util.BigArrays;
import org.elasticsearch.index.IndexService;
@ -67,11 +62,7 @@ import org.elasticsearch.search.rescore.RescoreSearchContext;
import org.elasticsearch.search.suggest.SuggestionSearchContext;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
/**
*
@ -206,7 +197,7 @@ public class DefaultSearchContext extends SearchContext {
parsedQuery(ParsedQuery.parsedMatchAllQuery());
}
if (queryBoost() != 1.0f) {
parsedQuery(new ParsedQuery(new FunctionScoreQuery(query(), new BoostScoreFunction(queryBoost)), parsedQuery()));
parsedQuery(new ParsedQuery(new FunctionScoreQuery(query(), new WeightFactorFunction(queryBoost)), parsedQuery()));
}
Query searchFilter = searchFilter(types());
if (searchFilter != null) {

View File

@ -70,7 +70,6 @@ import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.compress.CompressedXContent;
import org.elasticsearch.common.lucene.search.MoreLikeThisQuery;
import org.elasticsearch.common.lucene.search.Queries;
import org.elasticsearch.common.lucene.search.function.BoostScoreFunction;
import org.elasticsearch.common.lucene.search.function.FunctionScoreQuery;
import org.elasticsearch.common.lucene.search.function.WeightFactorFunction;
import org.elasticsearch.common.settings.Settings;
@ -2057,18 +2056,7 @@ public class SimpleIndexQueryParserTests extends ESSingleNodeTestCase {
IndexQueryParserService queryParser = queryParser();
String query = jsonBuilder().startObject().startObject("function_score")
.startArray("functions")
.startObject().field("weight", 2).field("boost_factor", 2).endObject()
.endArray()
.endObject().endObject().string();
try {
queryParser.parse(query).query();
fail("Expect exception here because boost_factor must not have a weight");
} catch (QueryParsingException e) {
assertThat(e.getDetailedMessage(), containsString(BoostScoreFunction.BOOST_WEIGHT_ERROR_MESSAGE));
}
query = jsonBuilder().startObject().startObject("function_score")
.startArray("functions")
.startObject().field("boost_factor",2).endObject()
.startObject().startObject("script_score").field("script", "3").endObject().endObject()
.endArray()
.field("weight", 2)
.endObject().endObject().string();
@ -2081,7 +2069,7 @@ public class SimpleIndexQueryParserTests extends ESSingleNodeTestCase {
query = jsonBuilder().startObject().startObject("function_score")
.field("weight", 2)
.startArray("functions")
.startObject().field("boost_factor",2).endObject()
.startObject().endObject()
.endArray()
.endObject().endObject().string();
try {

View File

@ -44,7 +44,7 @@ import org.elasticsearch.index.percolator.PercolatorException;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.QueryParsingException;
import org.elasticsearch.index.query.functionscore.factor.FactorBuilder;
import org.elasticsearch.index.query.functionscore.weight.WeightBuilder;
import org.elasticsearch.index.query.support.QueryInnerHitBuilder;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.script.Script;
@ -54,43 +54,16 @@ import org.elasticsearch.test.ESIntegTestCase;
import org.junit.Test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NavigableSet;
import java.util.Set;
import java.util.TreeSet;
import java.util.*;
import static org.elasticsearch.action.percolate.PercolateSourceBuilder.docBuilder;
import static org.elasticsearch.common.settings.Settings.builder;
import static org.elasticsearch.common.settings.Settings.settingsBuilder;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.common.xcontent.XContentFactory.smileBuilder;
import static org.elasticsearch.common.xcontent.XContentFactory.yamlBuilder;
import static org.elasticsearch.common.xcontent.XContentFactory.*;
import static org.elasticsearch.index.query.QueryBuilders.*;
import static org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders.scriptFunction;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAllSuccessful;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertMatchCount;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.arrayContaining;
import static org.hamcrest.Matchers.arrayContainingInAnyOrder;
import static org.hamcrest.Matchers.arrayWithSize;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.emptyArray;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.*;
import static org.hamcrest.Matchers.*;
/**
*
@ -1446,7 +1419,7 @@ public class PercolatorIT extends ESIntegTestCase {
.setSize(5)
.setPercolateDoc(docBuilder().setDoc(jsonBuilder().startObject().field("field1", "The quick brown fox jumps over the lazy dog").endObject()))
.setHighlightBuilder(new HighlightBuilder().field("field1"))
.setPercolateQuery(functionScoreQuery(matchAllQuery()).add(new FactorBuilder().boostFactor(5.5f)))
.setPercolateQuery(functionScoreQuery(matchAllQuery()).add(new WeightBuilder().setWeight(5.5f)))
.setScore(true)
.execute().actionGet();
assertNoFailures(response);
@ -1478,7 +1451,7 @@ public class PercolatorIT extends ESIntegTestCase {
.setSize(5)
.setPercolateDoc(docBuilder().setDoc(jsonBuilder().startObject().field("field1", "The quick brown fox jumps over the lazy dog").endObject()))
.setHighlightBuilder(new HighlightBuilder().field("field1"))
.setPercolateQuery(functionScoreQuery(matchAllQuery()).add(new FactorBuilder().boostFactor(5.5f)))
.setPercolateQuery(functionScoreQuery(matchAllQuery()).add(new WeightBuilder().setWeight(5.5f)))
.setSortByScore(true)
.execute().actionGet();
assertMatchCount(response, 5l);
@ -1510,7 +1483,7 @@ public class PercolatorIT extends ESIntegTestCase {
.setSize(5)
.setPercolateDoc(docBuilder().setDoc(jsonBuilder().startObject().field("field1", "The quick brown fox jumps over the lazy dog").endObject()))
.setHighlightBuilder(new HighlightBuilder().field("field1").highlightQuery(QueryBuilders.matchQuery("field1", "jumps")))
.setPercolateQuery(functionScoreQuery(matchAllQuery()).add(new FactorBuilder().boostFactor(5.5f)))
.setPercolateQuery(functionScoreQuery(matchAllQuery()).add(new WeightBuilder().setWeight(5.5f)))
.setSortByScore(true)
.execute().actionGet();
assertMatchCount(response, 5l);
@ -1547,7 +1520,7 @@ public class PercolatorIT extends ESIntegTestCase {
.setSize(5)
.setGetRequest(Requests.getRequest("test").type("type").id("1"))
.setHighlightBuilder(new HighlightBuilder().field("field1"))
.setPercolateQuery(functionScoreQuery(matchAllQuery()).add(new FactorBuilder().boostFactor(5.5f)))
.setPercolateQuery(functionScoreQuery(matchAllQuery()).add(new WeightBuilder().setWeight(5.5f)))
.setSortByScore(true)
.execute().actionGet();
assertMatchCount(response, 5l);

View File

@ -798,21 +798,8 @@ public class DecayFunctionScoreIT extends ESIntegTestCase {
refresh();
XContentBuilder query = XContentFactory.jsonBuilder();
// query that contains a functions[] array but also a single function
query.startObject().startObject("function_score").startArray("functions").startObject().field("boost_factor", "1.3").endObject().endArray().field("boost_factor", "1").endObject().endObject();
try {
client().search(
searchRequest().source(
searchSource().query(query))).actionGet();
fail("Search should result in SearchPhaseExecutionException");
} catch (SearchPhaseExecutionException e) {
logger.info(e.shardFailures()[0].reason());
assertThat(e.shardFailures()[0].reason(), containsString("already found [functions] array, now encountering [boost_factor]. did you mean [boost] instead?"));
}
query = XContentFactory.jsonBuilder();
// query that contains a single function and a functions[] array
query.startObject().startObject("function_score").field("boost_factor", "1").startArray("functions").startObject().field("boost_factor", "1.3").endObject().endArray().endObject().endObject();
query.startObject().startObject("function_score").field("weight", "1").startArray("functions").startObject().startObject("script_score").field("script", "3").endObject().endObject().endArray().endObject().endObject();
try {
client().search(
searchRequest().source(
@ -820,7 +807,7 @@ public class DecayFunctionScoreIT extends ESIntegTestCase {
fail("Search should result in SearchPhaseExecutionException");
} catch (SearchPhaseExecutionException e) {
logger.info(e.shardFailures()[0].reason());
assertThat(e.shardFailures()[0].reason(), containsString("already found [boost_factor], now encountering [functions]. did you mean [boost] instead?"));
assertThat(e.shardFailures()[0].reason(), containsString("already found [weight], now encountering [functions]."));
}
query = XContentFactory.jsonBuilder();
@ -888,7 +875,7 @@ public class DecayFunctionScoreIT extends ESIntegTestCase {
" \"text\": \"baseball\"\n" +
" }\n" +
" },\n" +
" \"boost_factor\": 2\n" +
" \"weight\": 2\n" +
" },\n" +
" {\n" +
" \"filter\": {\n" +

View File

@ -9,18 +9,12 @@
},
"functions": [
{
"boost_factor": 3,
"weight": 3,
"filter": {
term:{
"term":{
"name.last":"banon"
}
}
},
{
"boost_factor": 3
},
{
"boost_factor": 3
}
],
"boost" : 3,