Skip to content

Commit 2e9ea4a

Browse files
committed
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
1 parent b16fb69 commit 2e9ea4a

File tree

4 files changed

+72
-0
lines changed

4 files changed

+72
-0
lines changed

docs/reference/query-dsl/queries/simple-query-string-query.asciidoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ Defaults to `ROOT`.
4949

5050
|`lenient` | If set to `true` will cause format based failures
5151
(like providing text to a numeric field) to be ignored.
52+
53+
|`minimum_should_match` | The minimum number of clauses that must match for a
54+
document to be returned. See the
55+
<<query-dsl-minimum-should-match,`minimum_should_match`>> documentation for the
56+
full list of options.
5257
|=======================================================================
5358

5459
[float]

src/main/java/org/elasticsearch/index/query/SimpleQueryStringBuilder.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public class SimpleQueryStringBuilder extends BaseQueryBuilder {
3636
private Operator operator;
3737
private final String queryText;
3838
private String queryName;
39+
private String minimumShouldMatch;
3940
private int flags = -1;
4041
private Boolean lowercaseExpandedTerms;
4142
private Boolean lenient;
@@ -134,6 +135,11 @@ public SimpleQueryStringBuilder analyzeWildcard(boolean analyzeWildcard) {
134135
return this;
135136
}
136137

138+
public SimpleQueryStringBuilder minimumShouldMatch(String minimumShouldMatch) {
139+
this.minimumShouldMatch = minimumShouldMatch;
140+
return this;
141+
}
142+
137143
@Override
138144
public void doXContent(XContentBuilder builder, Params params) throws IOException {
139145
builder.startObject(SimpleQueryStringParser.NAME);
@@ -186,6 +192,10 @@ public void doXContent(XContentBuilder builder, Params params) throws IOExceptio
186192
builder.field("_name", queryName);
187193
}
188194

195+
if (minimumShouldMatch != null) {
196+
builder.field("minimum_should_match", minimumShouldMatch);
197+
}
198+
189199
builder.endObject();
190200
}
191201
}

src/main/java/org/elasticsearch/index/query/SimpleQueryStringParser.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@
2121

2222
import org.apache.lucene.analysis.Analyzer;
2323
import org.apache.lucene.search.BooleanClause;
24+
import org.apache.lucene.search.BooleanQuery;
2425
import org.apache.lucene.search.Query;
2526
import org.elasticsearch.common.Strings;
2627
import org.elasticsearch.common.inject.Inject;
28+
import org.elasticsearch.common.lucene.search.Queries;
2729
import org.elasticsearch.common.regex.Regex;
2830
import org.elasticsearch.common.settings.Settings;
2931
import org.elasticsearch.common.util.LocaleUtils;
@@ -89,6 +91,7 @@ public Query parse(QueryParseContext parseContext) throws IOException, QueryPars
8991
String queryBody = null;
9092
String queryName = null;
9193
String field = null;
94+
String minimumShouldMatch = null;
9295
Map<String, Float> fieldsAndWeights = null;
9396
BooleanClause.Occur defaultOperator = null;
9497
Analyzer analyzer = null;
@@ -182,6 +185,8 @@ public Query parse(QueryParseContext parseContext) throws IOException, QueryPars
182185
sqsSettings.analyzeWildcard(parser.booleanValue());
183186
} else if ("_name".equals(currentFieldName)) {
184187
queryName = parser.text();
188+
} else if ("minimum_should_match".equals(currentFieldName)) {
189+
minimumShouldMatch = parser.textOrNull();
185190
} else {
186191
throw new QueryParsingException(parseContext.index(), "[" + NAME + "] unsupported field [" + parser.currentName() + "]");
187192
}
@@ -221,6 +226,10 @@ public Query parse(QueryParseContext parseContext) throws IOException, QueryPars
221226
if (queryName != null) {
222227
parseContext.addNamedQuery(queryName, query);
223228
}
229+
230+
if (minimumShouldMatch != null && query instanceof BooleanQuery) {
231+
Queries.applyMinimumShouldMatch((BooleanQuery) query, minimumShouldMatch);
232+
}
224233
return query;
225234
}
226235
}

src/test/java/org/elasticsearch/search/query/SimpleQueryStringTests.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,54 @@ public void testSimpleQueryString() throws ExecutionException, InterruptedExcept
9191
assertSearchHits(searchResponse, "5", "6");
9292
}
9393

94+
@Test
95+
public void testSimpleQueryStringMinimumShouldMatch() throws Exception {
96+
createIndex("test");
97+
ensureGreen("test");
98+
indexRandom(true, false,
99+
client().prepareIndex("test", "type1", "1").setSource("body", "foo"),
100+
client().prepareIndex("test", "type1", "2").setSource("body", "bar"),
101+
client().prepareIndex("test", "type1", "3").setSource("body", "foo bar"),
102+
client().prepareIndex("test", "type1", "4").setSource("body", "foo baz bar"));
103+
104+
105+
logger.info("--> query 1");
106+
SearchResponse searchResponse = client().prepareSearch().setQuery(simpleQueryStringQuery("foo bar").minimumShouldMatch("2")).get();
107+
assertHitCount(searchResponse, 2l);
108+
assertSearchHits(searchResponse, "3", "4");
109+
110+
logger.info("--> query 2");
111+
searchResponse = client().prepareSearch().setQuery(simpleQueryStringQuery("foo bar").field("body").field("body2").minimumShouldMatch("2")).get();
112+
assertHitCount(searchResponse, 2l);
113+
assertSearchHits(searchResponse, "3", "4");
114+
115+
logger.info("--> query 3");
116+
searchResponse = client().prepareSearch().setQuery(simpleQueryStringQuery("foo bar baz").field("body").field("body2").minimumShouldMatch("70%")).get();
117+
assertHitCount(searchResponse, 2l);
118+
assertSearchHits(searchResponse, "3", "4");
119+
120+
indexRandom(true, false,
121+
client().prepareIndex("test", "type1", "5").setSource("body2", "foo", "other", "foo"),
122+
client().prepareIndex("test", "type1", "6").setSource("body2", "bar", "other", "foo"),
123+
client().prepareIndex("test", "type1", "7").setSource("body2", "foo bar", "other", "foo"),
124+
client().prepareIndex("test", "type1", "8").setSource("body2", "foo baz bar", "other", "foo"));
125+
126+
logger.info("--> query 4");
127+
searchResponse = client().prepareSearch().setQuery(simpleQueryStringQuery("foo bar").field("body").field("body2").minimumShouldMatch("2")).get();
128+
assertHitCount(searchResponse, 4l);
129+
assertSearchHits(searchResponse, "3", "4", "7", "8");
130+
131+
logger.info("--> query 5");
132+
searchResponse = client().prepareSearch().setQuery(simpleQueryStringQuery("foo bar").minimumShouldMatch("2")).get();
133+
assertHitCount(searchResponse, 5l);
134+
assertSearchHits(searchResponse, "3", "4", "6", "7", "8");
135+
136+
logger.info("--> query 6");
137+
searchResponse = client().prepareSearch().setQuery(simpleQueryStringQuery("foo bar baz").field("body2").field("other").minimumShouldMatch("70%")).get();
138+
assertHitCount(searchResponse, 3l);
139+
assertSearchHits(searchResponse, "6", "7", "8");
140+
}
141+
94142
@Test
95143
public void testSimpleQueryStringLowercasing() {
96144
createIndex("test");

0 commit comments

Comments
 (0)