Fixed NPE in multi_match query when using lenient and field weight

Closes #3797
This commit is contained in:
Helton Alponti 2013-10-24 16:09:01 -02:00 committed by Luca Cavanna
parent cc4bc7d57d
commit 0e9c049da1
2 changed files with 27 additions and 16 deletions

View File

@ -46,11 +46,14 @@ public class MultiMatchQuery extends MatchQuery {
super(parseContext); super(parseContext);
} }
private Query parseAndApply(Type type, String fieldName, Object value, String minimumShouldMatch) throws IOException { private Query parseAndApply(Type type, String fieldName, Object value, String minimumShouldMatch, Float boostValue) throws IOException {
Query query = parse(type, fieldName, value); Query query = parse(type, fieldName, value);
if (query instanceof BooleanQuery) { if (query instanceof BooleanQuery) {
Queries.applyMinimumShouldMatch((BooleanQuery) query, minimumShouldMatch); Queries.applyMinimumShouldMatch((BooleanQuery) query, minimumShouldMatch);
} }
if (boostValue != null && query != null) {
query.setBoost(boostValue);
}
return query; return query;
} }
@ -58,23 +61,15 @@ public class MultiMatchQuery extends MatchQuery {
if (fieldNames.size() == 1) { if (fieldNames.size() == 1) {
Map.Entry<String, Float> fieldBoost = fieldNames.entrySet().iterator().next(); Map.Entry<String, Float> fieldBoost = fieldNames.entrySet().iterator().next();
Float boostValue = fieldBoost.getValue(); Float boostValue = fieldBoost.getValue();
final Query query = parseAndApply(type, fieldBoost.getKey(), value, minimumShouldMatch); return parseAndApply(type, fieldBoost.getKey(), value, minimumShouldMatch, boostValue);
if (boostValue != null) {
query.setBoost(boostValue);
}
return query;
} }
if (useDisMax) { if (useDisMax) {
DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(tieBreaker); DisjunctionMaxQuery disMaxQuery = new DisjunctionMaxQuery(tieBreaker);
boolean clauseAdded = false; boolean clauseAdded = false;
for (String fieldName : fieldNames.keySet()) { for (String fieldName : fieldNames.keySet()) {
Query query = parseAndApply(type, fieldName, value, minimumShouldMatch);
Float boostValue = fieldNames.get(fieldName); Float boostValue = fieldNames.get(fieldName);
if (boostValue != null) { Query query = parseAndApply(type, fieldName, value, minimumShouldMatch, boostValue);
query.setBoost(boostValue);
}
if (query != null) { if (query != null) {
clauseAdded = true; clauseAdded = true;
disMaxQuery.add(query); disMaxQuery.add(query);
@ -84,11 +79,8 @@ public class MultiMatchQuery extends MatchQuery {
} else { } else {
BooleanQuery booleanQuery = new BooleanQuery(); BooleanQuery booleanQuery = new BooleanQuery();
for (String fieldName : fieldNames.keySet()) { for (String fieldName : fieldNames.keySet()) {
Query query = parseAndApply(type, fieldName, value, minimumShouldMatch);
Float boostValue = fieldNames.get(fieldName); Float boostValue = fieldNames.get(fieldName);
if (boostValue != null) { Query query = parseAndApply(type, fieldName, value, minimumShouldMatch, boostValue);
query.setBoost(boostValue);
}
if (query != null) { if (query != null) {
booleanQuery.add(query, BooleanClause.Occur.SHOULD); booleanQuery.add(query, BooleanClause.Occur.SHOULD);
} }

View File

@ -60,7 +60,6 @@ import static org.hamcrest.Matchers.*;
*/ */
public class SimpleQueryTests extends AbstractIntegrationTest { public class SimpleQueryTests extends AbstractIntegrationTest {
@Test // see https://github.com/elasticsearch/elasticsearch/issues/3177 @Test // see https://github.com/elasticsearch/elasticsearch/issues/3177
public void testIssue3177() { public void testIssue3177() {
run(prepareCreate("test").setSettings(ImmutableSettings.settingsBuilder().put("index.number_of_shards", 1))); run(prepareCreate("test").setSettings(ImmutableSettings.settingsBuilder().put("index.number_of_shards", 1)));
@ -1794,4 +1793,24 @@ public class SimpleQueryTests extends AbstractIntegrationTest {
assertHitCount(response, 1l); assertHitCount(response, 1l);
} }
@Test // see https://github.com/elasticsearch/elasticsearch/issues/3797
public void testMultiMatchLenientIssue3797() {
createIndex("test");
ensureGreen();
client().prepareIndex("test", "type1", "1").setSource("field1", 123, "field2", "value2").get();
refresh();
SearchResponse searchResponse = client().prepareSearch("test")
.setQuery(QueryBuilders.multiMatchQuery("value2", "field1^2", "field2").lenient(true).useDisMax(false)).get();
assertHitCount(searchResponse, 1l);
searchResponse = client().prepareSearch("test")
.setQuery(QueryBuilders.multiMatchQuery("value2", "field1^2", "field2").lenient(true).useDisMax(true)).get();
assertHitCount(searchResponse, 1l);
searchResponse = client().prepareSearch("test")
.setQuery(QueryBuilders.multiMatchQuery("value2", "field2^2").lenient(true)).get();
assertHitCount(searchResponse, 1l);
}
} }