Fixes MultiMatchQuery so that it doesn't provide a null context (#20882)

Before this change the `MultiMatchQuery` called the field types
`termQuery()` with a null context. This is not correct so this change
fixes this so the `MultiMatchQuery` now uses the `ShardQueryContext` it
stores as a field.

Relates to https://github.com/elastic/elasticsearch/pull/20796#pullrequestreview-3606305
This commit is contained in:
Colin Goodheart-Smithe 2016-10-13 08:44:41 +01:00 committed by GitHub
parent 1bcd26627c
commit 71aa807acd
3 changed files with 31 additions and 7 deletions

View File

@ -227,7 +227,7 @@ public class MultiMatchQuery extends MatchQuery {
if (blendedFields == null) {
return super.blendTerm(term, fieldType);
}
return MultiMatchQuery.blendTerm(term.bytes(), commonTermsCutoff, tieBreaker, blendedFields);
return MultiMatchQuery.blendTerm(context, term.bytes(), commonTermsCutoff, tieBreaker, blendedFields);
}
@Override
@ -241,7 +241,8 @@ public class MultiMatchQuery extends MatchQuery {
}
}
static Query blendTerm(BytesRef value, Float commonTermsCutoff, float tieBreaker, FieldAndFieldType... blendedFields) {
static Query blendTerm(QueryShardContext context, BytesRef value, Float commonTermsCutoff, float tieBreaker,
FieldAndFieldType... blendedFields) {
List<Query> queries = new ArrayList<>();
Term[] terms = new Term[blendedFields.length];
float[] blendedBoost = new float[blendedFields.length];
@ -249,7 +250,7 @@ public class MultiMatchQuery extends MatchQuery {
for (FieldAndFieldType ft : blendedFields) {
Query query;
try {
query = ft.fieldType.termQuery(value, null);
query = ft.fieldType.termQuery(value, context);
} catch (IllegalArgumentException e) {
// the query expects a certain class of values such as numbers
// of ip addresses and the value can't be parsed, so ignore this

View File

@ -101,7 +101,8 @@ public class MultiMatchQueryTests extends ESSingleNodeTestCase {
Term[] terms = new Term[] { new Term("foo", "baz"), new Term("bar", "baz") };
float[] boosts = new float[] {2, 3};
Query expected = BlendedTermQuery.booleanBlendedQuery(terms, boosts, false);
Query actual = MultiMatchQuery.blendTerm(new BytesRef("baz"), null, 1f, new FieldAndFieldType(ft1, 2), new FieldAndFieldType(ft2, 3));
Query actual = MultiMatchQuery.blendTerm(indexService.newQueryShardContext(), new BytesRef("baz"), null, 1f,
new FieldAndFieldType(ft1, 2), new FieldAndFieldType(ft2, 3));
assertEquals(expected, actual);
}
@ -115,7 +116,8 @@ public class MultiMatchQueryTests extends ESSingleNodeTestCase {
Term[] terms = new Term[] { new Term("foo", "baz"), new Term("bar", "baz") };
float[] boosts = new float[] {200, 30};
Query expected = BlendedTermQuery.booleanBlendedQuery(terms, boosts, false);
Query actual = MultiMatchQuery.blendTerm(new BytesRef("baz"), null, 1f, new FieldAndFieldType(ft1, 2), new FieldAndFieldType(ft2, 3));
Query actual = MultiMatchQuery.blendTerm(indexService.newQueryShardContext(), new BytesRef("baz"), null, 1f,
new FieldAndFieldType(ft1, 2), new FieldAndFieldType(ft2, 3));
assertEquals(expected, actual);
}
@ -132,7 +134,8 @@ public class MultiMatchQueryTests extends ESSingleNodeTestCase {
Term[] terms = new Term[] { new Term("foo", "baz") };
float[] boosts = new float[] {2};
Query expected = BlendedTermQuery.booleanBlendedQuery(terms, boosts, false);
Query actual = MultiMatchQuery.blendTerm(new BytesRef("baz"), null, 1f, new FieldAndFieldType(ft1, 2), new FieldAndFieldType(ft2, 3));
Query actual = MultiMatchQuery.blendTerm(indexService.newQueryShardContext(), new BytesRef("baz"), null, 1f,
new FieldAndFieldType(ft1, 2), new FieldAndFieldType(ft2, 3));
assertEquals(expected, actual);
}
@ -154,7 +157,8 @@ public class MultiMatchQueryTests extends ESSingleNodeTestCase {
.add(expectedClause1, Occur.SHOULD)
.add(expectedClause2, Occur.SHOULD)
.build();
Query actual = MultiMatchQuery.blendTerm(new BytesRef("baz"), null, 1f, new FieldAndFieldType(ft1, 2), new FieldAndFieldType(ft2, 3));
Query actual = MultiMatchQuery.blendTerm(indexService.newQueryShardContext(), new BytesRef("baz"), null, 1f,
new FieldAndFieldType(ft1, 2), new FieldAndFieldType(ft2, 3));
assertEquals(expected, actual);
}

View File

@ -122,6 +122,13 @@ public class MultiMatchQueryIT extends ESIntegTestCase {
"last_name", "",
"category", "marvel hero",
"skill", 1));
builders.add(client().prepareIndex("test", "test", "nowHero").setSource(
"full_name", "now sort of",
"first_name", "now",
"last_name", "",
"category", "marvel hero",
"skill", 1));
List<String> firstNames = new ArrayList<>();
fill(firstNames, "Captain", between(15, 25));
fill(firstNames, "Ultimate", between(5, 10));
@ -164,6 +171,9 @@ public class MultiMatchQueryIT extends ESIntegTestCase {
.field("norms", false)
.field("copy_to", "last_name_phrase")
.endObject()
.startObject("date")
.field("type", "date")
.endObject()
.endObject()
.endObject().endObject();
}
@ -633,6 +643,15 @@ public class MultiMatchQueryIT extends ESIntegTestCase {
.lenient(true))).get();
assertHitCount(searchResponse, 1L);
assertFirstHit(searchResponse, hasId("ultimate1"));
// Check that cross fields works with date fields
searchResponse = client().prepareSearch("test")
.setQuery(randomizeType(multiMatchQuery("now", "f*", "date")
.type(MultiMatchQueryBuilder.Type.CROSS_FIELDS)).lenient(true))
.get();
assertHitCount(searchResponse, 1L);
assertFirstHit(searchResponse, hasId("nowHero"));
}
/**