Restore tiebreaker for cross fields query (#28935)

This commit restores the handling of tiebreaker for multi_match
cross fields query. This functionality was lost during a refactoring
of the multi_match query (#25115).

Fixes #28933
This commit is contained in:
Jim Ferenczi 2018-03-12 09:58:20 +01:00 committed by GitHub
parent 0d78a5890e
commit 7afe5ad943
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 17 deletions

View File

@ -82,7 +82,7 @@ public class MultiMatchQuery extends MatchQuery {
queryBuilder = new QueryBuilder(tieBreaker);
break;
case CROSS_FIELDS:
queryBuilder = new CrossFieldsQueryBuilder();
queryBuilder = new CrossFieldsQueryBuilder(tieBreaker);
break;
default:
throw new IllegalStateException("No such type: " + type);
@ -152,8 +152,8 @@ public class MultiMatchQuery extends MatchQuery {
final class CrossFieldsQueryBuilder extends QueryBuilder {
private FieldAndFieldType[] blendedFields;
CrossFieldsQueryBuilder() {
super(0.0f);
CrossFieldsQueryBuilder(float tiebreaker) {
super(tiebreaker);
}
@Override
@ -239,7 +239,7 @@ public class MultiMatchQuery extends MatchQuery {
/**
* We build phrase queries for multi-word synonyms when {@link QueryBuilder#autoGenerateSynonymsPhraseQuery} is true.
*/
return MultiMatchQuery.blendPhrase(query, blendedFields);
return MultiMatchQuery.blendPhrase(query, tieBreaker, blendedFields);
}
}
@ -307,7 +307,7 @@ public class MultiMatchQuery extends MatchQuery {
* Expand a {@link PhraseQuery} to multiple fields that share the same analyzer.
* Returns a {@link DisjunctionMaxQuery} with a disjunction for each expanded field.
*/
static Query blendPhrase(PhraseQuery query, FieldAndFieldType... fields) {
static Query blendPhrase(PhraseQuery query, float tiebreaker, FieldAndFieldType... fields) {
List<Query> disjunctions = new ArrayList<>();
for (FieldAndFieldType field : fields) {
int[] positions = query.getPositions();
@ -322,7 +322,7 @@ public class MultiMatchQuery extends MatchQuery {
}
disjunctions.add(q);
}
return new DisjunctionMaxQuery(disjunctions, 0.0f);
return new DisjunctionMaxQuery(disjunctions, tiebreaker);
}
@Override

View File

@ -95,17 +95,24 @@ public class MultiMatchQueryTests extends ESSingleNodeTestCase {
QueryShardContext queryShardContext = indexService.newQueryShardContext(
randomInt(20), null, () -> { throw new UnsupportedOperationException(); }, null);
queryShardContext.setAllowUnmappedFields(true);
Query parsedQuery = multiMatchQuery("banon").field("name.first", 2).field("name.last", 3).field("foobar").type(MultiMatchQueryBuilder.Type.CROSS_FIELDS).toQuery(queryShardContext);
try (Engine.Searcher searcher = indexService.getShard(0).acquireSearcher("test")) {
Query rewrittenQuery = searcher.searcher().rewrite(parsedQuery);
Query tq1 = new BoostQuery(new TermQuery(new Term("name.first", "banon")), 2);
Query tq2 = new BoostQuery(new TermQuery(new Term("name.last", "banon")), 3);
Query expected = new DisjunctionMaxQuery(
Arrays.asList(
new MatchNoDocsQuery("unknown field foobar"),
new DisjunctionMaxQuery(Arrays.asList(tq2, tq1), 0f)
), 0f);
assertEquals(expected, rewrittenQuery);
for (float tieBreaker : new float[] {0.0f, 0.5f}) {
Query parsedQuery = multiMatchQuery("banon")
.field("name.first", 2)
.field("name.last", 3).field("foobar")
.type(MultiMatchQueryBuilder.Type.CROSS_FIELDS)
.tieBreaker(tieBreaker)
.toQuery(queryShardContext);
try (Engine.Searcher searcher = indexService.getShard(0).acquireSearcher("test")) {
Query rewrittenQuery = searcher.searcher().rewrite(parsedQuery);
Query tq1 = new BoostQuery(new TermQuery(new Term("name.first", "banon")), 2);
Query tq2 = new BoostQuery(new TermQuery(new Term("name.last", "banon")), 3);
Query expected = new DisjunctionMaxQuery(
Arrays.asList(
new MatchNoDocsQuery("unknown field foobar"),
new DisjunctionMaxQuery(Arrays.asList(tq2, tq1), tieBreaker)
), tieBreaker);
assertEquals(expected, rewrittenQuery);
}
}
}