Skip to content

Commit 14c11a9

Browse files
committed
MinimumNumberShouldMatch inconcistency, closes elastic#2194
Streamline the use of minimum should match to all relevant queries to accept `minimum_should_match`, and allow all relevant queries to accept the advanced "string" based config
1 parent 177568a commit 14c11a9

File tree

4 files changed

+33
-22
lines changed

4 files changed

+33
-22
lines changed

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

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@
2727

2828
/**
2929
* A Query that matches documents matching boolean combinations of other queries.
30-
*
31-
*
3230
*/
3331
public class BoolQueryBuilder extends BaseQueryBuilder implements BoostableQueryBuilder<BoolQueryBuilder> {
3432

@@ -42,7 +40,7 @@ public class BoolQueryBuilder extends BaseQueryBuilder implements BoostableQuery
4240

4341
private Boolean disableCoord;
4442

45-
private int minimumNumberShouldMatch = -1;
43+
private String minimumShouldMatch;
4644

4745
/**
4846
* Adds a query that <b>must</b> appear in the matching documents.
@@ -103,7 +101,15 @@ public BoolQueryBuilder disableCoord(boolean disableCoord) {
103101
* @param minimumNumberShouldMatch the number of optional clauses that must match
104102
*/
105103
public BoolQueryBuilder minimumNumberShouldMatch(int minimumNumberShouldMatch) {
106-
this.minimumNumberShouldMatch = minimumNumberShouldMatch;
104+
this.minimumShouldMatch = Integer.toString(minimumNumberShouldMatch);
105+
return this;
106+
}
107+
108+
/**
109+
* Sets the minimum should match using the special syntax (for example, supporting percentage).
110+
*/
111+
public BoolQueryBuilder minimumShouldMatch(String minimumShouldMatch) {
112+
this.minimumShouldMatch = minimumShouldMatch;
107113
return this;
108114
}
109115

@@ -126,8 +132,8 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep
126132
if (disableCoord != null) {
127133
builder.field("disable_coord", disableCoord);
128134
}
129-
if (minimumNumberShouldMatch != -1) {
130-
builder.field("minimum_number_should_match", minimumNumberShouldMatch);
135+
if (minimumShouldMatch != null) {
136+
builder.field("minimum_should_match", minimumShouldMatch);
131137
}
132138
builder.endObject();
133139
}

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

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.apache.lucene.search.BooleanQuery;
2424
import org.apache.lucene.search.Query;
2525
import org.elasticsearch.common.inject.Inject;
26+
import org.elasticsearch.common.lucene.search.Queries;
2627
import org.elasticsearch.common.settings.Settings;
2728
import org.elasticsearch.common.xcontent.XContentParser;
2829

@@ -56,7 +57,7 @@ public Query parse(QueryParseContext parseContext) throws IOException, QueryPars
5657

5758
boolean disableCoord = false;
5859
float boost = 1.0f;
59-
int minimumNumberShouldMatch = -1;
60+
String minimumShouldMatch = null;
6061

6162
List<BooleanClause> clauses = newArrayList();
6263

@@ -112,12 +113,12 @@ public Query parse(QueryParseContext parseContext) throws IOException, QueryPars
112113
} else if (token.isValue()) {
113114
if ("disable_coord".equals(currentFieldName) || "disableCoord".equals(currentFieldName)) {
114115
disableCoord = parser.booleanValue();
115-
} else if ("minimum_number_should_match".equals(currentFieldName) || "minimumNumberShouldMatch".equals(currentFieldName)) {
116-
minimumNumberShouldMatch = parser.intValue();
117116
} else if ("minimum_should_match".equals(currentFieldName) || "minimumShouldMatch".equals(currentFieldName)) {
118-
minimumNumberShouldMatch = parser.intValue();
117+
minimumShouldMatch = parser.textOrNull();
119118
} else if ("boost".equals(currentFieldName)) {
120119
boost = parser.floatValue();
120+
} else if ("minimum_number_should_match".equals(currentFieldName) || "minimumNumberShouldMatch".equals(currentFieldName)) {
121+
minimumShouldMatch = parser.textOrNull();
121122
} else {
122123
throw new QueryParsingException(parseContext.index(), "[bool] query does not support [" + currentFieldName + "]");
123124
}
@@ -133,9 +134,7 @@ public Query parse(QueryParseContext parseContext) throws IOException, QueryPars
133134
query.add(clause);
134135
}
135136
query.setBoost(boost);
136-
if (minimumNumberShouldMatch != -1) {
137-
query.setMinimumNumberShouldMatch(minimumNumberShouldMatch);
138-
}
137+
Queries.applyMinimumShouldMatch(query, minimumShouldMatch);
139138
return optimizeQuery(fixNegativeQueryIfNeeded(query));
140139
}
141140
}

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public class TermsQueryBuilder extends BaseQueryBuilder implements BoostableQuer
3232

3333
private final Object[] values;
3434

35-
private int minimumMatch = -1;
35+
private String minimumShouldMatch;
3636

3737
private Boolean disableCoord;
3838

@@ -119,7 +119,12 @@ public TermsQueryBuilder(String name, Object... values) {
119119
* Sets the minimum number of matches across the provided terms. Defaults to <tt>1</tt>.
120120
*/
121121
public TermsQueryBuilder minimumMatch(int minimumMatch) {
122-
this.minimumMatch = minimumMatch;
122+
this.minimumShouldMatch = Integer.toString(minimumMatch);
123+
return this;
124+
}
125+
126+
public TermsQueryBuilder minimumShouldMatch(String minimumShouldMatch) {
127+
this.minimumShouldMatch = minimumShouldMatch;
123128
return this;
124129
}
125130

@@ -149,8 +154,8 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep
149154
}
150155
builder.endArray();
151156

152-
if (minimumMatch != -1) {
153-
builder.field("minimum_match", minimumMatch);
157+
if (minimumShouldMatch != null) {
158+
builder.field("minimum_should_match", minimumShouldMatch);
154159
}
155160
if (disableCoord != null) {
156161
builder.field("disable_coord", disableCoord);

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.apache.lucene.search.Query;
2626
import org.apache.lucene.search.TermQuery;
2727
import org.elasticsearch.common.inject.Inject;
28+
import org.elasticsearch.common.lucene.search.Queries;
2829
import org.elasticsearch.common.xcontent.XContentParser;
2930
import org.elasticsearch.index.mapper.FieldMapper;
3031
import org.elasticsearch.index.mapper.MapperService;
@@ -65,7 +66,7 @@ public Query parse(QueryParseContext parseContext) throws IOException, QueryPars
6566
String fieldName = null;
6667
boolean disableCoord = false;
6768
float boost = 1.0f;
68-
int minimumNumberShouldMatch = 1;
69+
String minimumShouldMatch = null;
6970
List<String> values = newArrayList();
7071

7172
String currentFieldName = null;
@@ -86,7 +87,9 @@ public Query parse(QueryParseContext parseContext) throws IOException, QueryPars
8687
if ("disable_coord".equals(currentFieldName) || "disableCoord".equals(currentFieldName)) {
8788
disableCoord = parser.booleanValue();
8889
} else if ("minimum_match".equals(currentFieldName) || "minimumMatch".equals(currentFieldName)) {
89-
minimumNumberShouldMatch = parser.intValue();
90+
minimumShouldMatch = parser.textOrNull();
91+
} else if ("minimum_should_match".equals(currentFieldName) || "minimumShouldMatch".equals(currentFieldName)) {
92+
minimumShouldMatch = parser.textOrNull();
9093
} else if ("boost".equals(currentFieldName)) {
9194
boost = parser.floatValue();
9295
}
@@ -115,9 +118,7 @@ public Query parse(QueryParseContext parseContext) throws IOException, QueryPars
115118
}
116119
}
117120
query.setBoost(boost);
118-
if (minimumNumberShouldMatch != -1) {
119-
query.setMinimumNumberShouldMatch(minimumNumberShouldMatch);
120-
}
121+
Queries.applyMinimumShouldMatch(query, minimumShouldMatch);
121122
return wrapSmartNameQuery(optimizeQuery(fixNegativeQueryIfNeeded(query)), smartNameFieldMappers, parseContext);
122123
} finally {
123124
if (smartNameFieldMappers != null && smartNameFieldMappers.explicitTypeInNameWithDocMapper()) {

0 commit comments

Comments
 (0)