Add support for `minimum_should_match` to `simple_query_string`
This behaves similar to the way that `minimum_should_match` works for the `match` query (in fact it is implemented in the exact same way) Fixes #6449
This commit is contained in:
parent
b16fb69315
commit
2e9ea4abaf
|
@ -49,6 +49,11 @@ Defaults to `ROOT`.
|
||||||
|
|
||||||
|`lenient` | If set to `true` will cause format based failures
|
|`lenient` | If set to `true` will cause format based failures
|
||||||
(like providing text to a numeric field) to be ignored.
|
(like providing text to a numeric field) to be ignored.
|
||||||
|
|
||||||
|
|`minimum_should_match` | The minimum number of clauses that must match for a
|
||||||
|
document to be returned. See the
|
||||||
|
<<query-dsl-minimum-should-match,`minimum_should_match`>> documentation for the
|
||||||
|
full list of options.
|
||||||
|=======================================================================
|
|=======================================================================
|
||||||
|
|
||||||
[float]
|
[float]
|
||||||
|
|
|
@ -36,6 +36,7 @@ public class SimpleQueryStringBuilder extends BaseQueryBuilder {
|
||||||
private Operator operator;
|
private Operator operator;
|
||||||
private final String queryText;
|
private final String queryText;
|
||||||
private String queryName;
|
private String queryName;
|
||||||
|
private String minimumShouldMatch;
|
||||||
private int flags = -1;
|
private int flags = -1;
|
||||||
private Boolean lowercaseExpandedTerms;
|
private Boolean lowercaseExpandedTerms;
|
||||||
private Boolean lenient;
|
private Boolean lenient;
|
||||||
|
@ -134,6 +135,11 @@ public class SimpleQueryStringBuilder extends BaseQueryBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SimpleQueryStringBuilder minimumShouldMatch(String minimumShouldMatch) {
|
||||||
|
this.minimumShouldMatch = minimumShouldMatch;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doXContent(XContentBuilder builder, Params params) throws IOException {
|
public void doXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
builder.startObject(SimpleQueryStringParser.NAME);
|
builder.startObject(SimpleQueryStringParser.NAME);
|
||||||
|
@ -186,6 +192,10 @@ public class SimpleQueryStringBuilder extends BaseQueryBuilder {
|
||||||
builder.field("_name", queryName);
|
builder.field("_name", queryName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (minimumShouldMatch != null) {
|
||||||
|
builder.field("minimum_should_match", minimumShouldMatch);
|
||||||
|
}
|
||||||
|
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,9 +21,11 @@ package org.elasticsearch.index.query;
|
||||||
|
|
||||||
import org.apache.lucene.analysis.Analyzer;
|
import org.apache.lucene.analysis.Analyzer;
|
||||||
import org.apache.lucene.search.BooleanClause;
|
import org.apache.lucene.search.BooleanClause;
|
||||||
|
import org.apache.lucene.search.BooleanQuery;
|
||||||
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.Queries;
|
||||||
import org.elasticsearch.common.regex.Regex;
|
import org.elasticsearch.common.regex.Regex;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.LocaleUtils;
|
import org.elasticsearch.common.util.LocaleUtils;
|
||||||
|
@ -89,6 +91,7 @@ public class SimpleQueryStringParser implements QueryParser {
|
||||||
String queryBody = null;
|
String queryBody = null;
|
||||||
String queryName = null;
|
String queryName = null;
|
||||||
String field = null;
|
String field = null;
|
||||||
|
String minimumShouldMatch = null;
|
||||||
Map<String, Float> fieldsAndWeights = null;
|
Map<String, Float> fieldsAndWeights = null;
|
||||||
BooleanClause.Occur defaultOperator = null;
|
BooleanClause.Occur defaultOperator = null;
|
||||||
Analyzer analyzer = null;
|
Analyzer analyzer = null;
|
||||||
|
@ -182,6 +185,8 @@ public class SimpleQueryStringParser implements QueryParser {
|
||||||
sqsSettings.analyzeWildcard(parser.booleanValue());
|
sqsSettings.analyzeWildcard(parser.booleanValue());
|
||||||
} else if ("_name".equals(currentFieldName)) {
|
} else if ("_name".equals(currentFieldName)) {
|
||||||
queryName = parser.text();
|
queryName = parser.text();
|
||||||
|
} else if ("minimum_should_match".equals(currentFieldName)) {
|
||||||
|
minimumShouldMatch = parser.textOrNull();
|
||||||
} else {
|
} else {
|
||||||
throw new QueryParsingException(parseContext.index(), "[" + NAME + "] unsupported field [" + parser.currentName() + "]");
|
throw new QueryParsingException(parseContext.index(), "[" + NAME + "] unsupported field [" + parser.currentName() + "]");
|
||||||
}
|
}
|
||||||
|
@ -221,6 +226,10 @@ public class SimpleQueryStringParser implements QueryParser {
|
||||||
if (queryName != null) {
|
if (queryName != null) {
|
||||||
parseContext.addNamedQuery(queryName, query);
|
parseContext.addNamedQuery(queryName, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (minimumShouldMatch != null && query instanceof BooleanQuery) {
|
||||||
|
Queries.applyMinimumShouldMatch((BooleanQuery) query, minimumShouldMatch);
|
||||||
|
}
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,6 +91,54 @@ public class SimpleQueryStringTests extends ElasticsearchIntegrationTest {
|
||||||
assertSearchHits(searchResponse, "5", "6");
|
assertSearchHits(searchResponse, "5", "6");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSimpleQueryStringMinimumShouldMatch() throws Exception {
|
||||||
|
createIndex("test");
|
||||||
|
ensureGreen("test");
|
||||||
|
indexRandom(true, false,
|
||||||
|
client().prepareIndex("test", "type1", "1").setSource("body", "foo"),
|
||||||
|
client().prepareIndex("test", "type1", "2").setSource("body", "bar"),
|
||||||
|
client().prepareIndex("test", "type1", "3").setSource("body", "foo bar"),
|
||||||
|
client().prepareIndex("test", "type1", "4").setSource("body", "foo baz bar"));
|
||||||
|
|
||||||
|
|
||||||
|
logger.info("--> query 1");
|
||||||
|
SearchResponse searchResponse = client().prepareSearch().setQuery(simpleQueryStringQuery("foo bar").minimumShouldMatch("2")).get();
|
||||||
|
assertHitCount(searchResponse, 2l);
|
||||||
|
assertSearchHits(searchResponse, "3", "4");
|
||||||
|
|
||||||
|
logger.info("--> query 2");
|
||||||
|
searchResponse = client().prepareSearch().setQuery(simpleQueryStringQuery("foo bar").field("body").field("body2").minimumShouldMatch("2")).get();
|
||||||
|
assertHitCount(searchResponse, 2l);
|
||||||
|
assertSearchHits(searchResponse, "3", "4");
|
||||||
|
|
||||||
|
logger.info("--> query 3");
|
||||||
|
searchResponse = client().prepareSearch().setQuery(simpleQueryStringQuery("foo bar baz").field("body").field("body2").minimumShouldMatch("70%")).get();
|
||||||
|
assertHitCount(searchResponse, 2l);
|
||||||
|
assertSearchHits(searchResponse, "3", "4");
|
||||||
|
|
||||||
|
indexRandom(true, false,
|
||||||
|
client().prepareIndex("test", "type1", "5").setSource("body2", "foo", "other", "foo"),
|
||||||
|
client().prepareIndex("test", "type1", "6").setSource("body2", "bar", "other", "foo"),
|
||||||
|
client().prepareIndex("test", "type1", "7").setSource("body2", "foo bar", "other", "foo"),
|
||||||
|
client().prepareIndex("test", "type1", "8").setSource("body2", "foo baz bar", "other", "foo"));
|
||||||
|
|
||||||
|
logger.info("--> query 4");
|
||||||
|
searchResponse = client().prepareSearch().setQuery(simpleQueryStringQuery("foo bar").field("body").field("body2").minimumShouldMatch("2")).get();
|
||||||
|
assertHitCount(searchResponse, 4l);
|
||||||
|
assertSearchHits(searchResponse, "3", "4", "7", "8");
|
||||||
|
|
||||||
|
logger.info("--> query 5");
|
||||||
|
searchResponse = client().prepareSearch().setQuery(simpleQueryStringQuery("foo bar").minimumShouldMatch("2")).get();
|
||||||
|
assertHitCount(searchResponse, 5l);
|
||||||
|
assertSearchHits(searchResponse, "3", "4", "6", "7", "8");
|
||||||
|
|
||||||
|
logger.info("--> query 6");
|
||||||
|
searchResponse = client().prepareSearch().setQuery(simpleQueryStringQuery("foo bar baz").field("body2").field("other").minimumShouldMatch("70%")).get();
|
||||||
|
assertHitCount(searchResponse, 3l);
|
||||||
|
assertSearchHits(searchResponse, "6", "7", "8");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSimpleQueryStringLowercasing() {
|
public void testSimpleQueryStringLowercasing() {
|
||||||
createIndex("test");
|
createIndex("test");
|
||||||
|
|
Loading…
Reference in New Issue