allow no query is defined in function score, default is match all
This commit is contained in:
parent
31097691af
commit
f12fa0c1c4
|
@ -550,6 +550,24 @@ public abstract class QueryBuilders {
|
||||||
public static FunctionScoreQueryBuilder functionScoreQuery(QueryBuilder queryBuilder) {
|
public static FunctionScoreQueryBuilder functionScoreQuery(QueryBuilder queryBuilder) {
|
||||||
return new FunctionScoreQueryBuilder(queryBuilder);
|
return new FunctionScoreQueryBuilder(queryBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A query that allows to define a custom scoring function.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static FunctionScoreQueryBuilder functionScoreQuery() {
|
||||||
|
return new FunctionScoreQueryBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A query that allows to define a custom scoring function.
|
||||||
|
*
|
||||||
|
* @param filterBuilder The filterBuilder to custom score
|
||||||
|
*/
|
||||||
|
public static FunctionScoreQueryBuilder functionScoreQuery(ScoreFunctionBuilder function) {
|
||||||
|
return new FunctionScoreQueryBuilder(function);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A query that allows to define a custom scoring function.
|
* A query that allows to define a custom scoring function.
|
||||||
*
|
*
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
package org.elasticsearch.index.query.functionscore;
|
package org.elasticsearch.index.query.functionscore;
|
||||||
|
|
||||||
import org.elasticsearch.ElasticSearchException;
|
|
||||||
import org.elasticsearch.common.lucene.search.function.CombineFunction;
|
import org.elasticsearch.common.lucene.search.function.CombineFunction;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.index.query.BaseQueryBuilder;
|
import org.elasticsearch.index.query.BaseQueryBuilder;
|
||||||
|
@ -61,6 +60,18 @@ public class FunctionScoreQueryBuilder extends BaseQueryBuilder implements Boost
|
||||||
this.queryBuilder = null;
|
this.queryBuilder = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FunctionScoreQueryBuilder() {
|
||||||
|
this.filterBuilder = null;
|
||||||
|
this.queryBuilder = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FunctionScoreQueryBuilder(ScoreFunctionBuilder scoreFunctionBuilder) {
|
||||||
|
queryBuilder = null;
|
||||||
|
filterBuilder = null;
|
||||||
|
this.filters.add(null);
|
||||||
|
this.scoreFunctions.add(scoreFunctionBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
public FunctionScoreQueryBuilder add(FilterBuilder filter, ScoreFunctionBuilder scoreFunctionBuilder) {
|
public FunctionScoreQueryBuilder add(FilterBuilder filter, ScoreFunctionBuilder scoreFunctionBuilder) {
|
||||||
this.filters.add(filter);
|
this.filters.add(filter);
|
||||||
this.scoreFunctions.add(scoreFunctionBuilder);
|
this.scoreFunctions.add(scoreFunctionBuilder);
|
||||||
|
@ -112,10 +123,7 @@ public class FunctionScoreQueryBuilder extends BaseQueryBuilder implements Boost
|
||||||
} else if (filterBuilder != null) {
|
} else if (filterBuilder != null) {
|
||||||
builder.field("filter");
|
builder.field("filter");
|
||||||
filterBuilder.toXContent(builder, params);
|
filterBuilder.toXContent(builder, params);
|
||||||
} else {
|
}
|
||||||
throw new ElasticSearchException(FunctionScoreQueryParser.NAME
|
|
||||||
+ " builder requires that either a filter or a query is defined!");
|
|
||||||
}
|
|
||||||
// If there is only one function without a filter, we later want to
|
// If there is only one function without a filter, we later want to
|
||||||
// create a FunctionScoreQuery.
|
// create a FunctionScoreQuery.
|
||||||
// For this, we only build the scoreFunction.Tthis will be translated to
|
// For this, we only build the scoreFunction.Tthis will be translated to
|
||||||
|
|
|
@ -23,7 +23,7 @@ import org.apache.lucene.search.Filter;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.lucene.search.MatchAllDocsFilter;
|
import org.elasticsearch.common.lucene.search.Queries;
|
||||||
import org.elasticsearch.common.lucene.search.XConstantScoreQuery;
|
import org.elasticsearch.common.lucene.search.XConstantScoreQuery;
|
||||||
import org.elasticsearch.common.lucene.search.function.CombineFunction;
|
import org.elasticsearch.common.lucene.search.function.CombineFunction;
|
||||||
import org.elasticsearch.common.lucene.search.function.FiltersFunctionScoreQuery;
|
import org.elasticsearch.common.lucene.search.function.FiltersFunctionScoreQuery;
|
||||||
|
@ -95,7 +95,7 @@ public class FunctionScoreQueryParser implements QueryParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (query == null) {
|
if (query == null) {
|
||||||
throw new QueryParsingException(parseContext.index(), NAME + " requires 'query' field");
|
query = Queries.newMatchAllQuery();
|
||||||
}
|
}
|
||||||
// if all filter elements returned null, just use the query
|
// if all filter elements returned null, just use the query
|
||||||
if (filterFunctions.isEmpty()) {
|
if (filterFunctions.isEmpty()) {
|
||||||
|
@ -150,7 +150,7 @@ public class FunctionScoreQueryParser implements QueryParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (filter == null) {
|
if (filter == null) {
|
||||||
filter = new MatchAllDocsFilter();
|
filter = Queries.MATCH_ALL_FILTER;
|
||||||
}
|
}
|
||||||
filterFunctions.add(new FiltersFunctionScoreQuery.FilterFunction(filter, scoreFunction));
|
filterFunctions.add(new FiltersFunctionScoreQuery.FilterFunction(filter, scoreFunction));
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ import org.apache.lucene.search.spans.*;
|
||||||
import org.apache.lucene.spatial.prefix.IntersectsPrefixTreeFilter;
|
import org.apache.lucene.spatial.prefix.IntersectsPrefixTreeFilter;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
import org.apache.lucene.util.NumericUtils;
|
import org.apache.lucene.util.NumericUtils;
|
||||||
|
import org.elasticsearch.ElasticsearchTestCase;
|
||||||
import org.elasticsearch.cache.recycler.CacheRecyclerModule;
|
import org.elasticsearch.cache.recycler.CacheRecyclerModule;
|
||||||
import org.elasticsearch.cluster.ClusterService;
|
import org.elasticsearch.cluster.ClusterService;
|
||||||
import org.elasticsearch.common.bytes.BytesArray;
|
import org.elasticsearch.common.bytes.BytesArray;
|
||||||
|
@ -63,7 +64,6 @@ import org.elasticsearch.index.settings.IndexSettingsModule;
|
||||||
import org.elasticsearch.index.similarity.SimilarityModule;
|
import org.elasticsearch.index.similarity.SimilarityModule;
|
||||||
import org.elasticsearch.indices.query.IndicesQueriesModule;
|
import org.elasticsearch.indices.query.IndicesQueriesModule;
|
||||||
import org.elasticsearch.script.ScriptModule;
|
import org.elasticsearch.script.ScriptModule;
|
||||||
import org.elasticsearch.ElasticsearchTestCase;
|
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.threadpool.ThreadPoolModule;
|
import org.elasticsearch.threadpool.ThreadPoolModule;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
|
@ -1478,6 +1478,17 @@ public class SimpleIndexQueryParserTests extends ElasticsearchTestCase {
|
||||||
assertThat(((TermQuery) functionScoreQuery.getSubQuery()).getTerm(), equalTo(new Term("name.last", "banon")));
|
assertThat(((TermQuery) functionScoreQuery.getSubQuery()).getTerm(), equalTo(new Term("name.last", "banon")));
|
||||||
assertThat((double) ((BoostScoreFunction) functionScoreQuery.getFunction()).getBoost(), closeTo(1.3, 0.001));
|
assertThat((double) ((BoostScoreFunction) functionScoreQuery.getFunction()).getBoost(), closeTo(1.3, 0.001));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCustomBoostFactorQueryBuilder_withFunctionScoreWithoutQueryGiven() throws IOException {
|
||||||
|
IndexQueryParserService queryParser = queryParser();
|
||||||
|
Query parsedQuery = queryParser.parse(functionScoreQuery(factorFunction(1.3f))).query();
|
||||||
|
assertThat(parsedQuery, instanceOf(FunctionScoreQuery.class));
|
||||||
|
FunctionScoreQuery functionScoreQuery = (FunctionScoreQuery) parsedQuery;
|
||||||
|
assertThat(functionScoreQuery.getSubQuery() instanceof XConstantScoreQuery, equalTo(true));
|
||||||
|
assertThat(((XConstantScoreQuery)functionScoreQuery.getSubQuery()).getFilter() instanceof MatchAllDocsFilter, equalTo(true));
|
||||||
|
assertThat((double) ((BoostScoreFunction) functionScoreQuery.getFunction()).getBoost(), closeTo(1.3, 0.001));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -560,7 +560,7 @@ public class DecayFunctionScoreTests extends AbstractSharedClusterTest {
|
||||||
.add(new MatchAllFilterBuilder(), linearDecayFunction("date", "2013-05-30", "+15d"))
|
.add(new MatchAllFilterBuilder(), linearDecayFunction("date", "2013-05-30", "+15d"))
|
||||||
.add(new MatchAllFilterBuilder(), linearDecayFunction("geo", lonlat, "1000km"))
|
.add(new MatchAllFilterBuilder(), linearDecayFunction("geo", lonlat, "1000km"))
|
||||||
.add(new MatchAllFilterBuilder(),
|
.add(new MatchAllFilterBuilder(),
|
||||||
linearDecayFunction("num", Integer.toString(numDocs), Integer.toString(numDocs / 2)))
|
linearDecayFunction("num", numDocs, numDocs / 2.0))
|
||||||
.scoreMode("multiply").boostMode(CombineFunction.REPLACE.getName()))));
|
.scoreMode("multiply").boostMode(CombineFunction.REPLACE.getName()))));
|
||||||
|
|
||||||
SearchResponse sr = response.actionGet();
|
SearchResponse sr = response.actionGet();
|
||||||
|
@ -623,8 +623,29 @@ public class DecayFunctionScoreTests extends AbstractSharedClusterTest {
|
||||||
searchRequest().searchType(SearchType.QUERY_THEN_FETCH).source(
|
searchRequest().searchType(SearchType.QUERY_THEN_FETCH).source(
|
||||||
searchSource().explain(true).query(
|
searchSource().explain(true).query(
|
||||||
functionScoreQuery(termQuery("test", "value")).add(new MatchAllFilterBuilder(),
|
functionScoreQuery(termQuery("test", "value")).add(new MatchAllFilterBuilder(),
|
||||||
linearDecayFunction("num", Integer.toString(1), Integer.toString(1 / 2))).scoreMode("multiply"))));
|
linearDecayFunction("num", 1.0, 0.5)).scoreMode("multiply"))));
|
||||||
|
response.actionGet();
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
public void testNoQueryGiven() throws Exception {
|
||||||
|
assertAcked(prepareCreate("test").addMapping("type",
|
||||||
|
jsonBuilder().startObject().startObject("type").startObject("properties")
|
||||||
|
.startObject("test").field("type", "string").endObject()
|
||||||
|
.startObject("num").field("type", "double").endObject()
|
||||||
|
.endObject().endObject().endObject()));
|
||||||
|
ensureYellow();
|
||||||
|
client().index(
|
||||||
|
indexRequest("test").type("type").source(
|
||||||
|
jsonBuilder().startObject().field("test", "value").field("num", 1.0).endObject())).actionGet();
|
||||||
|
refresh();
|
||||||
|
// so, we indexed a string field, but now we try to score a num field
|
||||||
|
ActionFuture<SearchResponse> response = client().search(
|
||||||
|
searchRequest().searchType(SearchType.QUERY_THEN_FETCH).source(
|
||||||
|
searchSource().explain(true).query(
|
||||||
|
functionScoreQuery().add(new MatchAllFilterBuilder(),
|
||||||
|
linearDecayFunction("num", 1, 0.5)).scoreMode("multiply"))));
|
||||||
response.actionGet();
|
response.actionGet();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue