Apply QueryParser boost to top leve query if applicable.
Set the query boost of a parsed query string query to the product of the parsed query boost and the boost value specified in the "boost" query string parameter. This only applies if the top level query returned from the query parser has a boost assigned to it. In such a case we must multiply the boost with the top level query boost otherwise the boost will be overwritten ie. 'foo^2' has a top-level boost of 2 while 'foo^2 OR bar^3' has a top level boost of 1.0 (default) since the boolean query is the top level query. Closes #3024
This commit is contained in:
parent
af4205fd30
commit
927fda8a61
|
@ -34,10 +34,11 @@ public class QueryParserSettings {
|
|||
|
||||
public static final boolean DEFAULT_ALLOW_LEADING_WILDCARD = true;
|
||||
public static final boolean DEFAULT_ANALYZE_WILDCARD = false;
|
||||
public static final float DEFAULT_BOOST = 1.f;
|
||||
|
||||
private String queryString;
|
||||
private String defaultField;
|
||||
private float boost = 1.0f;
|
||||
private float boost = DEFAULT_BOOST;
|
||||
private MapperQueryParser.Operator defaultOperator = QueryParser.Operator.OR;
|
||||
private boolean autoGeneratePhraseQueries = false;
|
||||
private boolean allowLeadingWildcard = DEFAULT_ALLOW_LEADING_WILDCARD;
|
||||
|
|
|
@ -214,7 +214,9 @@ public class QueryStringQueryParser implements QueryParser {
|
|||
if (query == null) {
|
||||
return null;
|
||||
}
|
||||
query.setBoost(qpSettings.boost());
|
||||
if (qpSettings.boost() != QueryParserSettings.DEFAULT_BOOST) {
|
||||
query.setBoost(query.getBoost() * qpSettings.boost());
|
||||
}
|
||||
query = optimizeQuery(fixNegativeQueryIfNeeded(query));
|
||||
if (query instanceof BooleanQuery) {
|
||||
Queries.applyMinimumShouldMatch((BooleanQuery) query, qpSettings.minimumShouldMatch());
|
||||
|
|
|
@ -23,6 +23,8 @@ import static org.hamcrest.Matchers.*;
|
|||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.lucene.search.BooleanQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
import org.elasticsearch.search.SearchHit;
|
||||
import org.elasticsearch.search.suggest.Suggest;
|
||||
|
@ -107,5 +109,13 @@ public class ElasticsearchAssertions {
|
|||
public static Matcher<SearchHit> hasIndex(final String index) {
|
||||
return new ElasticsearchMatchers.SearchHitHasIndexMatcher(index);
|
||||
}
|
||||
|
||||
public static <T extends Query> T assertBooleanSubQuery(Query query, Class<T> subqueryType, int i) {
|
||||
assertThat(query, instanceOf(BooleanQuery.class));
|
||||
BooleanQuery q = (BooleanQuery) query;
|
||||
assertThat(q.getClauses().length, greaterThan(i));
|
||||
assertThat(q.getClauses()[i].getQuery(), instanceOf(subqueryType));
|
||||
return (T)q.getClauses()[i].getQuery();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ import org.elasticsearch.index.mapper.MapperServiceModule;
|
|||
import org.elasticsearch.index.query.IndexQueryParserModule;
|
||||
import org.elasticsearch.index.query.IndexQueryParserService;
|
||||
import org.elasticsearch.index.query.ParsedQuery;
|
||||
import org.elasticsearch.index.query.QueryStringQueryBuilder;
|
||||
import org.elasticsearch.index.search.NumericRangeFieldDataFilter;
|
||||
import org.elasticsearch.index.search.geo.GeoDistanceFilter;
|
||||
import org.elasticsearch.index.search.geo.GeoPolygonFilter;
|
||||
|
@ -80,6 +81,7 @@ import static org.elasticsearch.index.query.QueryBuilders.*;
|
|||
import static org.elasticsearch.index.query.RegexpFlag.*;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.*;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -160,6 +162,31 @@ public class SimpleIndexQueryParserTests {
|
|||
assertThat(termQuery.getTerm(), equalTo(new Term("content", "test")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryStringBoostsBuilder() throws Exception {
|
||||
IndexQueryParserService queryParser = queryParser();
|
||||
QueryStringQueryBuilder builder = queryString("field:boosted^2");
|
||||
Query parsedQuery = queryParser.parse(builder).query();
|
||||
assertThat(parsedQuery, instanceOf(TermQuery.class));
|
||||
assertThat(((TermQuery) parsedQuery).getTerm(), equalTo(new Term("field", "boosted")));
|
||||
assertThat(parsedQuery.getBoost(), equalTo(2.0f));
|
||||
builder.boost(2.0f);
|
||||
parsedQuery = queryParser.parse(builder).query();
|
||||
assertThat(parsedQuery.getBoost(), equalTo(4.0f));
|
||||
|
||||
builder = queryString("((field:boosted^2) AND (field:foo^1.5))^3");
|
||||
parsedQuery = queryParser.parse(builder).query();
|
||||
assertThat(parsedQuery, instanceOf(BooleanQuery.class));
|
||||
assertThat(assertBooleanSubQuery(parsedQuery, TermQuery.class, 0).getTerm(), equalTo(new Term("field", "boosted")));
|
||||
assertThat(assertBooleanSubQuery(parsedQuery, TermQuery.class, 0).getBoost(), equalTo(2.0f));
|
||||
assertThat(assertBooleanSubQuery(parsedQuery, TermQuery.class, 1).getTerm(), equalTo(new Term("field", "foo")));
|
||||
assertThat(assertBooleanSubQuery(parsedQuery, TermQuery.class, 1).getBoost(), equalTo(1.5f));
|
||||
assertThat(parsedQuery.getBoost(), equalTo(3.0f));
|
||||
builder.boost(2.0f);
|
||||
parsedQuery = queryParser.parse(builder).query();
|
||||
assertThat(parsedQuery.getBoost(), equalTo(6.0f));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryStringFields1Builder() throws Exception {
|
||||
IndexQueryParserService queryParser = queryParser();
|
||||
|
@ -167,8 +194,8 @@ public class SimpleIndexQueryParserTests {
|
|||
assertThat(parsedQuery, instanceOf(BooleanQuery.class));
|
||||
BooleanQuery bQuery = (BooleanQuery) parsedQuery;
|
||||
assertThat(bQuery.clauses().size(), equalTo(2));
|
||||
assertThat(((TermQuery) bQuery.clauses().get(0).getQuery()).getTerm(), equalTo(new Term("content", "test")));
|
||||
assertThat(((TermQuery) bQuery.clauses().get(1).getQuery()).getTerm(), equalTo(new Term("name", "test")));
|
||||
assertThat(assertBooleanSubQuery(parsedQuery, TermQuery.class, 0).getTerm(), equalTo(new Term("content", "test")));
|
||||
assertThat(assertBooleanSubQuery(parsedQuery, TermQuery.class, 1).getTerm(), equalTo(new Term("name", "test")));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -179,8 +206,8 @@ public class SimpleIndexQueryParserTests {
|
|||
assertThat(parsedQuery, instanceOf(BooleanQuery.class));
|
||||
BooleanQuery bQuery = (BooleanQuery) parsedQuery;
|
||||
assertThat(bQuery.clauses().size(), equalTo(2));
|
||||
assertThat(((TermQuery) bQuery.clauses().get(0).getQuery()).getTerm(), equalTo(new Term("content", "test")));
|
||||
assertThat(((TermQuery) bQuery.clauses().get(1).getQuery()).getTerm(), equalTo(new Term("name", "test")));
|
||||
assertThat(assertBooleanSubQuery(parsedQuery, TermQuery.class, 0).getTerm(), equalTo(new Term("content", "test")));
|
||||
assertThat(assertBooleanSubQuery(parsedQuery, TermQuery.class, 1).getTerm(), equalTo(new Term("name", "test")));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -191,8 +218,8 @@ public class SimpleIndexQueryParserTests {
|
|||
assertThat(parsedQuery, instanceOf(BooleanQuery.class));
|
||||
BooleanQuery bQuery = (BooleanQuery) parsedQuery;
|
||||
assertThat(bQuery.clauses().size(), equalTo(2));
|
||||
assertThat(((TermQuery) bQuery.clauses().get(0).getQuery()).getTerm(), equalTo(new Term("name.first", "test")));
|
||||
assertThat(((TermQuery) bQuery.clauses().get(1).getQuery()).getTerm(), equalTo(new Term("name.last", "test")));
|
||||
assertThat(assertBooleanSubQuery(parsedQuery, TermQuery.class, 0).getTerm(), equalTo(new Term("name.first", "test")));
|
||||
assertThat(assertBooleanSubQuery(parsedQuery, TermQuery.class, 1).getTerm(), equalTo(new Term("name.last", "test")));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Reference in New Issue