Fix cross fields mode of the query_string query (#34216)

This change fixes a bug in the cross fields mode of the `query_string`
query. The multi fields query builder must be reseted before parsing
in order to clear the list of expanded fields coming from the previous text block.

Closes #34215
This commit is contained in:
Jim Ferenczi 2018-10-02 14:53:26 +02:00 committed by GitHub
parent 3f8cc89c9f
commit ead6ffce54
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 15 deletions

View File

@ -67,7 +67,9 @@ public class MultiMatchQuery extends MatchQuery {
} }
public Query parse(MultiMatchQueryBuilder.Type type, Map<String, Float> fieldNames, Object value, String minimumShouldMatch) throws IOException { public Query parse(MultiMatchQueryBuilder.Type type, Map<String, Float> fieldNames, Object value, String minimumShouldMatch) throws IOException {
Query result; final Query result;
// reset query builder
queryBuilder = null;
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();

View File

@ -21,6 +21,7 @@ package org.elasticsearch.index.query;
import org.apache.lucene.analysis.MockSynonymAnalyzer; import org.apache.lucene.analysis.MockSynonymAnalyzer;
import org.apache.lucene.index.Term; import org.apache.lucene.index.Term;
import org.apache.lucene.queries.BlendedTermQuery;
import org.apache.lucene.search.BooleanClause; import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanClause.Occur; import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.BooleanQuery;
@ -1195,20 +1196,23 @@ public class QueryStringQueryBuilderTests extends AbstractQueryTestCase<QueryStr
newIndexMeta("index", context.getIndexSettings().getSettings(), Settings.builder().putList("index.query.default_field", newIndexMeta("index", context.getIndexSettings().getSettings(), Settings.builder().putList("index.query.default_field",
STRING_FIELD_NAME, STRING_FIELD_NAME_2 + "^5").build()) STRING_FIELD_NAME, STRING_FIELD_NAME_2 + "^5").build())
); );
Query query = new QueryStringQueryBuilder("hello") try {
.toQuery(context); Query query = new QueryStringQueryBuilder("hello")
Query expected = new DisjunctionMaxQuery( .toQuery(context);
Arrays.asList( Query expected = new DisjunctionMaxQuery(
new TermQuery(new Term(STRING_FIELD_NAME, "hello")), Arrays.asList(
new BoostQuery(new TermQuery(new Term(STRING_FIELD_NAME_2, "hello")), 5.0f) new TermQuery(new Term(STRING_FIELD_NAME, "hello")),
), 0.0f new BoostQuery(new TermQuery(new Term(STRING_FIELD_NAME_2, "hello")), 5.0f)
); ), 0.0f
assertEquals(expected, query); );
// Reset the default value assertEquals(expected, query);
context.getIndexSettings().updateIndexMetaData( } finally {
newIndexMeta("index", // Reset the default value
context.getIndexSettings().getSettings(), Settings.builder().putList("index.query.default_field", "*").build()) context.getIndexSettings().updateIndexMetaData(
); newIndexMeta("index",
context.getIndexSettings().getSettings(), Settings.builder().putList("index.query.default_field", "*").build())
);
}
} }
/** /**
@ -1345,6 +1349,44 @@ public class QueryStringQueryBuilderTests extends AbstractQueryTestCase<QueryStr
assertEquals(expected, query); assertEquals(expected, query);
} }
public void testCrossFields() throws Exception {
final QueryShardContext context = createShardContext();
context.getIndexSettings().updateIndexMetaData(
newIndexMeta("index", context.getIndexSettings().getSettings(),
Settings.builder().putList("index.query.default_field",
STRING_FIELD_NAME, STRING_FIELD_NAME_2).build())
);
try {
Term[] blendedTerms = new Term[2];
blendedTerms[0] = new Term(STRING_FIELD_NAME, "foo");
blendedTerms[1] = new Term(STRING_FIELD_NAME_2, "foo");
Query query = new QueryStringQueryBuilder("foo")
.analyzer("whitespace")
.type(MultiMatchQueryBuilder.Type.CROSS_FIELDS)
.toQuery(createShardContext());
Query expected = BlendedTermQuery.dismaxBlendedQuery(blendedTerms, 1.0f);
assertEquals(expected, query);
query = new QueryStringQueryBuilder("foo mapped_string:10")
.analyzer("whitespace")
.type(MultiMatchQueryBuilder.Type.CROSS_FIELDS)
.toQuery(createShardContext());
expected = new BooleanQuery.Builder()
.add(BlendedTermQuery.dismaxBlendedQuery(blendedTerms, 1.0f), Occur.SHOULD)
.add(new TermQuery(new Term(STRING_FIELD_NAME, "10")), Occur.SHOULD)
.build();
assertEquals(expected, query);
} finally {
// Reset the default value
context.getIndexSettings().updateIndexMetaData(
newIndexMeta("index",
context.getIndexSettings().getSettings(),
Settings.builder().putList("index.query.default_field", "*").build())
);
}
}
private static IndexMetaData newIndexMeta(String name, Settings oldIndexSettings, Settings indexSettings) { private static IndexMetaData newIndexMeta(String name, Settings oldIndexSettings, Settings indexSettings) {
Settings build = Settings.builder().put(oldIndexSettings) Settings build = Settings.builder().put(oldIndexSettings)
.put(indexSettings) .put(indexSettings)