- Fixed boosting per field with multi_match query.
This commit is contained in:
parent
fbd352b448
commit
b6a9bd9a31
|
@ -63,8 +63,7 @@ public class MultiMatchQueryParser implements QueryParser {
|
|||
MatchQuery.Type type = MatchQuery.Type.BOOLEAN;
|
||||
MultiMatchQuery multiMatchQuery = new MultiMatchQuery(parseContext);
|
||||
String minimumShouldMatch = null;
|
||||
List<String> fieldNames = Lists.newArrayList();
|
||||
Map<String, Float> fieldNameToBoost = Maps.newHashMap();
|
||||
Map<String, Float> fieldNameWithBoosts = Maps.newHashMap();
|
||||
|
||||
XContentParser.Token token;
|
||||
String currentFieldName = null;
|
||||
|
@ -75,7 +74,7 @@ public class MultiMatchQueryParser implements QueryParser {
|
|||
if ("fields".equals(currentFieldName)) {
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||
String fField = null;
|
||||
float fBoost = -1;
|
||||
Float fBoost = null;
|
||||
char[] fieldText = parser.textCharacters();
|
||||
int end = parser.textOffset() + parser.textLength();
|
||||
for (int i = parser.textOffset(); i < end; i++) {
|
||||
|
@ -92,16 +91,10 @@ public class MultiMatchQueryParser implements QueryParser {
|
|||
|
||||
if (Regex.isSimpleMatchPattern(fField)) {
|
||||
for (String field : parseContext.mapperService().simpleMatchToIndexNames(fField)) {
|
||||
fieldNames.add(field);
|
||||
if (fBoost != -1) {
|
||||
fieldNameToBoost.put(field, fBoost);
|
||||
}
|
||||
fieldNameWithBoosts.put(field, fBoost);
|
||||
}
|
||||
} else {
|
||||
fieldNames.add(fField);
|
||||
if (fBoost != -1) {
|
||||
fieldNameToBoost.put(fField, fBoost);
|
||||
}
|
||||
fieldNameWithBoosts.put(fField, fBoost);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -166,11 +159,11 @@ public class MultiMatchQueryParser implements QueryParser {
|
|||
throw new QueryParsingException(parseContext.index(), "No text specified for match_all query");
|
||||
}
|
||||
|
||||
if (fieldNames.isEmpty()) {
|
||||
if (fieldNameWithBoosts.isEmpty()) {
|
||||
throw new QueryParsingException(parseContext.index(), "No fields specified for match_all query");
|
||||
}
|
||||
|
||||
Query query = multiMatchQuery.parse(type, fieldNames, text);
|
||||
Query query = multiMatchQuery.parse(type, fieldNameWithBoosts, text);
|
||||
if (query == null) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.apache.lucene.search.Query;
|
|||
import org.elasticsearch.index.query.QueryParseContext;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class MultiMatchQuery extends MatchQuery {
|
||||
|
||||
|
@ -44,16 +45,28 @@ public class MultiMatchQuery extends MatchQuery {
|
|||
super(parseContext);
|
||||
}
|
||||
|
||||
public Query parse(Type type, List<String> fieldNames, String text) {
|
||||
public Query parse(Type type, Map<String, Float> fieldNames, String text) {
|
||||
if (fieldNames.size() == 1) {
|
||||
return parse(type, fieldNames.get(0), text);
|
||||
Map.Entry<String, Float> fieldBoost = fieldNames.entrySet().iterator().next();
|
||||
Float boostValue = fieldBoost.getValue();
|
||||
if (boostValue == null) {
|
||||
return parse(type, fieldBoost.getKey(), text);
|
||||
} else {
|
||||
Query query = parse(type, fieldBoost.getKey(), text);
|
||||
query.setBoost(boostValue);
|
||||
return query;
|
||||
}
|
||||
}
|
||||
|
||||
if (useDisMax) {
|
||||
DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(tieBreaker);
|
||||
boolean clauseAdded = false;
|
||||
for (String fieldName : fieldNames) {
|
||||
for (String fieldName : fieldNames.keySet()) {
|
||||
Query query = parse(type, fieldName, text);
|
||||
Float boostValue = fieldNames.get(fieldName);
|
||||
if (boostValue != null) {
|
||||
query.setBoost(boostValue);
|
||||
}
|
||||
if (query != null) {
|
||||
clauseAdded = true;
|
||||
disMaxQuery.add(query);
|
||||
|
@ -62,8 +75,12 @@ public class MultiMatchQuery extends MatchQuery {
|
|||
return clauseAdded ? disMaxQuery : null;
|
||||
} else {
|
||||
BooleanQuery booleanQuery = new BooleanQuery();
|
||||
for (String fieldName : fieldNames) {
|
||||
for (String fieldName : fieldNames.keySet()) {
|
||||
Query query = parse(type, fieldName, text);
|
||||
Float boostValue = fieldNames.get(fieldName);
|
||||
if (boostValue != null) {
|
||||
query.setBoost(boostValue);
|
||||
}
|
||||
if (query != null) {
|
||||
booleanQuery.add(query, BooleanClause.Occur.SHOULD);
|
||||
}
|
||||
|
|
|
@ -409,9 +409,9 @@ public class SimpleQueryTests extends AbstractNodesTests {
|
|||
|
||||
client.admin().indices().prepareCreate("test").setSettings(ImmutableSettings.settingsBuilder().put("number_of_shards", 1)).execute().actionGet();
|
||||
|
||||
client.prepareIndex("test", "type1", "1").setSource("field1", "value1", "field2", "value4").execute().actionGet();
|
||||
client.prepareIndex("test", "type1", "2").setSource("field1", "value2", "field2", "value5").execute().actionGet();
|
||||
client.prepareIndex("test", "type1", "3").setSource("field1", "value3", "field2", "value6").execute().actionGet();
|
||||
client.prepareIndex("test", "type1", "1").setSource("field1", "value1", "field2", "value4", "field3", "value3").execute().actionGet();
|
||||
client.prepareIndex("test", "type1", "2").setSource("field1", "value2", "field2", "value5", "field3", "value2").execute().actionGet();
|
||||
client.prepareIndex("test", "type1", "3").setSource("field1", "value3", "field2", "value6", "field3", "value1").execute().actionGet();
|
||||
client.admin().indices().prepareRefresh("test").execute().actionGet();
|
||||
|
||||
MultiMatchQueryBuilder builder = QueryBuilders.multiMatchQuery("value1 value2 value4", "field1", "field2");
|
||||
|
@ -442,11 +442,21 @@ public class SimpleQueryTests extends AbstractNodesTests {
|
|||
assertThat(searchResponse.hits().totalHits(), equalTo(1l));
|
||||
assertThat("1", equalTo(searchResponse.hits().getAt(0).id()));
|
||||
|
||||
client.admin().indices().prepareRefresh("test").execute().actionGet();
|
||||
builder = QueryBuilders.multiMatchQuery("value1", "field1", "field3^1.5")
|
||||
.operator(MatchQueryBuilder.Operator.AND); // Operator only applies on terms inside a field! Fields are always OR-ed together.
|
||||
searchResponse = client.prepareSearch()
|
||||
.setQuery(builder)
|
||||
.execute().actionGet();
|
||||
assertThat(searchResponse.hits().totalHits(), equalTo(2l));
|
||||
assertThat("3", equalTo(searchResponse.hits().getAt(0).id()));
|
||||
assertThat("1", equalTo(searchResponse.hits().getAt(1).id()));
|
||||
|
||||
// Test lenient
|
||||
client.prepareIndex("test", "type1", "3").setSource("field1", "value7", "field2", "value8", "field3", 5).execute().actionGet();
|
||||
client.prepareIndex("test", "type1", "3").setSource("field1", "value7", "field2", "value8", "field4", 5).execute().actionGet();
|
||||
client.admin().indices().prepareRefresh("test").execute().actionGet();
|
||||
|
||||
builder = QueryBuilders.multiMatchQuery("value1", "field1", "field2", "field3");
|
||||
builder = QueryBuilders.multiMatchQuery("value1", "field1", "field2", "field4");
|
||||
try {
|
||||
client.prepareSearch()
|
||||
.setQuery(builder)
|
||||
|
|
Loading…
Reference in New Issue