Apply minimum_should_match to inner clauses of multi_match query

When specifying minimum_should_match in a multi_match query it was being applied
to the outer bool query instead of to each of the inner field-specific bool queries.

Closes #2918
This commit is contained in:
Clinton Gormley 2013-04-19 17:02:41 +02:00 committed by Simon Willnauer
parent 3ab56e16b7
commit e508b27203
2 changed files with 17 additions and 15 deletions

View File

@ -21,10 +21,8 @@ package org.elasticsearch.index.query;
import com.google.common.collect.Maps;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Query;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.lucene.search.Queries;
import org.elasticsearch.common.regex.Regex;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.support.QueryParsers;
@ -172,15 +170,11 @@ public class MultiMatchQueryParser implements QueryParser {
throw new QueryParsingException(parseContext.index(), "No fields specified for match_all query");
}
Query query = multiMatchQuery.parse(type, fieldNameWithBoosts, value);
Query query = multiMatchQuery.parse(type, fieldNameWithBoosts, value, minimumShouldMatch);
if (query == null) {
return null;
}
if (query instanceof BooleanQuery) {
Queries.applyMinimumShouldMatch((BooleanQuery) query, minimumShouldMatch);
}
query.setBoost(boost);
return query;
}

View File

@ -23,6 +23,7 @@ import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.DisjunctionMaxQuery;
import org.apache.lucene.search.Query;
import org.elasticsearch.common.lucene.search.Queries;
import org.elasticsearch.index.query.QueryParseContext;
import java.io.IOException;
@ -44,29 +45,36 @@ public class MultiMatchQuery extends MatchQuery {
public MultiMatchQuery(QueryParseContext parseContext) {
super(parseContext);
}
private Query parseAndApply(Type type, String fieldName, Object value, String minimumShouldMatch) throws IOException {
Query query = parse(type, fieldName, value);
if (query instanceof BooleanQuery) {
Queries.applyMinimumShouldMatch((BooleanQuery) query, minimumShouldMatch);
}
return query;
}
public Query parse(Type type, Map<String, Float> fieldNames, Object value) throws IOException {
public Query parse(Type type, Map<String, Float> fieldNames, Object value, String minimumShouldMatch) throws IOException {
if (fieldNames.size() == 1) {
Map.Entry<String, Float> fieldBoost = fieldNames.entrySet().iterator().next();
Float boostValue = fieldBoost.getValue();
if (boostValue == null) {
return parse(type, fieldBoost.getKey(), value);
} else {
Query query = parse(type, fieldBoost.getKey(), value);
final Query query = parseAndApply(type, fieldBoost.getKey(), value, minimumShouldMatch);
if (boostValue != null) {
query.setBoost(boostValue);
return query;
}
return query;
}
if (useDisMax) {
DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(tieBreaker);
boolean clauseAdded = false;
for (String fieldName : fieldNames.keySet()) {
Query query = parse(type, fieldName, value);
Query query = parseAndApply(type, fieldName, value, minimumShouldMatch);
Float boostValue = fieldNames.get(fieldName);
if (boostValue != null) {
query.setBoost(boostValue);
}
if (query != null) {
clauseAdded = true;
disMaxQuery.add(query);
@ -76,7 +84,7 @@ public class MultiMatchQuery extends MatchQuery {
} else {
BooleanQuery booleanQuery = new BooleanQuery();
for (String fieldName : fieldNames.keySet()) {
Query query = parse(type, fieldName, value);
Query query = parseAndApply(type, fieldName, value, minimumShouldMatch);
Float boostValue = fieldNames.get(fieldName);
if (boostValue != null) {
query.setBoost(boostValue);