Fix multi fields empty query (#33017)
This change fixes empty query removal when all fields remove the search term in `simple_query_string`, `multi_match` and `query_string`. Closes #33009
This commit is contained in:
parent
f311680176
commit
8b43e21521
|
@ -328,8 +328,9 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
|||
/**
|
||||
* @param type Sets how multiple fields should be combined to build textual part queries.
|
||||
*/
|
||||
public void type(MultiMatchQueryBuilder.Type type) {
|
||||
public QueryStringQueryBuilder type(MultiMatchQueryBuilder.Type type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -388,7 +389,7 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
|||
this.analyzer = analyzer;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The optional analyzer used to analyze the query string. Note, if a field has search analyzer
|
||||
* defined for it, then it will be used automatically. Defaults to the smart search analyzer.
|
||||
|
@ -899,9 +900,9 @@ public class QueryStringQueryBuilder extends AbstractQueryBuilder<QueryStringQue
|
|||
Objects.equals(tieBreaker, other.tieBreaker) &&
|
||||
Objects.equals(rewrite, other.rewrite) &&
|
||||
Objects.equals(minimumShouldMatch, other.minimumShouldMatch) &&
|
||||
Objects.equals(lenient, other.lenient) &&
|
||||
Objects.equals(lenient, other.lenient) &&
|
||||
Objects.equals(
|
||||
timeZone == null ? null : timeZone.getID(),
|
||||
timeZone == null ? null : timeZone.getID(),
|
||||
other.timeZone == null ? null : other.timeZone.getID()) &&
|
||||
Objects.equals(escape, other.escape) &&
|
||||
Objects.equals(maxDeterminizedStates, other.maxDeterminizedStates) &&
|
||||
|
|
|
@ -120,7 +120,7 @@ public class MultiMatchQuery extends MatchQuery {
|
|||
|
||||
private Query combineGrouped(List<? extends Query> groupQuery) {
|
||||
if (groupQuery == null || groupQuery.isEmpty()) {
|
||||
return new MatchNoDocsQuery("[multi_match] list of group queries was empty");
|
||||
return zeroTermsQuery();
|
||||
}
|
||||
if (groupQuery.size() == 1) {
|
||||
return groupQuery.get(0);
|
||||
|
|
|
@ -347,6 +347,9 @@ public class QueryStringQueryParser extends XQueryParser {
|
|||
}
|
||||
queryBuilder.setPhraseSlop(slop);
|
||||
Query query = queryBuilder.parse(MultiMatchQueryBuilder.Type.PHRASE, fields, queryText, null);
|
||||
if (query == null) {
|
||||
return null;
|
||||
}
|
||||
return applySlop(query, slop);
|
||||
} catch (IOException e) {
|
||||
throw new ParseException(e.getMessage());
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.elasticsearch.index.query;
|
|||
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.queries.ExtendedCommonTermsQuery;
|
||||
import org.apache.lucene.search.BooleanClause;
|
||||
import org.apache.lucene.search.BooleanQuery;
|
||||
import org.apache.lucene.search.BoostQuery;
|
||||
import org.apache.lucene.search.DisjunctionMaxQuery;
|
||||
|
@ -381,6 +382,69 @@ public class MultiMatchQueryBuilderTests extends AbstractQueryTestCase<MultiMatc
|
|||
assertEquals(expected, query);
|
||||
}
|
||||
|
||||
public void testWithStopWords() throws Exception {
|
||||
Query query = new MultiMatchQueryBuilder("the quick fox")
|
||||
.field(STRING_FIELD_NAME)
|
||||
.analyzer("stop")
|
||||
.toQuery(createShardContext());
|
||||
Query expected = new BooleanQuery.Builder()
|
||||
.add(new TermQuery(new Term(STRING_FIELD_NAME, "quick")), BooleanClause.Occur.SHOULD)
|
||||
.add(new TermQuery(new Term(STRING_FIELD_NAME, "fox")), BooleanClause.Occur.SHOULD)
|
||||
.build();
|
||||
assertEquals(expected, query);
|
||||
|
||||
query = new MultiMatchQueryBuilder("the quick fox")
|
||||
.field(STRING_FIELD_NAME)
|
||||
.field(STRING_FIELD_NAME_2)
|
||||
.analyzer("stop")
|
||||
.toQuery(createShardContext());
|
||||
expected = new DisjunctionMaxQuery(
|
||||
Arrays.asList(
|
||||
new BooleanQuery.Builder()
|
||||
.add(new TermQuery(new Term(STRING_FIELD_NAME, "quick")), BooleanClause.Occur.SHOULD)
|
||||
.add(new TermQuery(new Term(STRING_FIELD_NAME, "fox")), BooleanClause.Occur.SHOULD)
|
||||
.build(),
|
||||
new BooleanQuery.Builder()
|
||||
.add(new TermQuery(new Term(STRING_FIELD_NAME_2, "quick")), BooleanClause.Occur.SHOULD)
|
||||
.add(new TermQuery(new Term(STRING_FIELD_NAME_2, "fox")), BooleanClause.Occur.SHOULD)
|
||||
.build()
|
||||
), 0f);
|
||||
assertEquals(expected, query);
|
||||
|
||||
query = new MultiMatchQueryBuilder("the")
|
||||
.field(STRING_FIELD_NAME)
|
||||
.field(STRING_FIELD_NAME_2)
|
||||
.analyzer("stop")
|
||||
.toQuery(createShardContext());
|
||||
expected = new DisjunctionMaxQuery(Arrays.asList(new MatchNoDocsQuery(), new MatchNoDocsQuery()), 0f);
|
||||
assertEquals(expected, query);
|
||||
|
||||
query = new BoolQueryBuilder()
|
||||
.should(
|
||||
new MultiMatchQueryBuilder("the")
|
||||
.field(STRING_FIELD_NAME)
|
||||
.analyzer("stop")
|
||||
)
|
||||
.toQuery(createShardContext());
|
||||
expected = new BooleanQuery.Builder()
|
||||
.add(new MatchNoDocsQuery(), BooleanClause.Occur.SHOULD)
|
||||
.build();
|
||||
assertEquals(expected, query);
|
||||
|
||||
query = new BoolQueryBuilder()
|
||||
.should(
|
||||
new MultiMatchQueryBuilder("the")
|
||||
.field(STRING_FIELD_NAME)
|
||||
.field(STRING_FIELD_NAME_2)
|
||||
.analyzer("stop")
|
||||
)
|
||||
.toQuery(createShardContext());
|
||||
expected = new BooleanQuery.Builder()
|
||||
.add(new DisjunctionMaxQuery(Arrays.asList(new MatchNoDocsQuery(), new MatchNoDocsQuery()), 0f), BooleanClause.Occur.SHOULD)
|
||||
.build();
|
||||
assertEquals(expected, query);
|
||||
}
|
||||
|
||||
private static IndexMetaData newIndexMeta(String name, Settings oldIndexSettings, Settings indexSettings) {
|
||||
Settings build = Settings.builder().put(oldIndexSettings)
|
||||
.put(indexSettings)
|
||||
|
|
|
@ -1266,11 +1266,58 @@ public class QueryStringQueryBuilderTests extends AbstractQueryTestCase<QueryStr
|
|||
.field(STRING_FIELD_NAME)
|
||||
.analyzer("stop")
|
||||
.toQuery(createShardContext());
|
||||
BooleanQuery expected = new BooleanQuery.Builder()
|
||||
.add(new TermQuery(new Term(STRING_FIELD_NAME, "quick")), Occur.SHOULD)
|
||||
.add(new TermQuery(new Term(STRING_FIELD_NAME, "fox")), Occur.SHOULD)
|
||||
Query expected = new BooleanQuery.Builder()
|
||||
.add(new TermQuery(new Term(STRING_FIELD_NAME, "quick")), BooleanClause.Occur.SHOULD)
|
||||
.add(new TermQuery(new Term(STRING_FIELD_NAME, "fox")), BooleanClause.Occur.SHOULD)
|
||||
.build();
|
||||
assertEquals(expected, query);
|
||||
|
||||
query = new QueryStringQueryBuilder("the quick fox")
|
||||
.field(STRING_FIELD_NAME)
|
||||
.field(STRING_FIELD_NAME_2)
|
||||
.analyzer("stop")
|
||||
.toQuery(createShardContext());
|
||||
expected = new DisjunctionMaxQuery(
|
||||
Arrays.asList(
|
||||
new BooleanQuery.Builder()
|
||||
.add(new TermQuery(new Term(STRING_FIELD_NAME, "quick")), Occur.SHOULD)
|
||||
.add(new TermQuery(new Term(STRING_FIELD_NAME, "fox")), Occur.SHOULD)
|
||||
.build(),
|
||||
new BooleanQuery.Builder()
|
||||
.add(new TermQuery(new Term(STRING_FIELD_NAME_2, "quick")), Occur.SHOULD)
|
||||
.add(new TermQuery(new Term(STRING_FIELD_NAME_2, "fox")), Occur.SHOULD)
|
||||
.build()
|
||||
), 0f);
|
||||
assertEquals(expected, query);
|
||||
|
||||
query = new QueryStringQueryBuilder("the")
|
||||
.field(STRING_FIELD_NAME)
|
||||
.field(STRING_FIELD_NAME_2)
|
||||
.analyzer("stop")
|
||||
.toQuery(createShardContext());
|
||||
assertEquals(new BooleanQuery.Builder().build(), query);
|
||||
|
||||
query = new BoolQueryBuilder()
|
||||
.should(
|
||||
new QueryStringQueryBuilder("the")
|
||||
.field(STRING_FIELD_NAME)
|
||||
.analyzer("stop")
|
||||
)
|
||||
.toQuery(createShardContext());
|
||||
expected = new BooleanQuery.Builder()
|
||||
.add(new BooleanQuery.Builder().build(), BooleanClause.Occur.SHOULD)
|
||||
.build();
|
||||
assertEquals(expected, query);
|
||||
|
||||
query = new BoolQueryBuilder()
|
||||
.should(
|
||||
new QueryStringQueryBuilder("the")
|
||||
.field(STRING_FIELD_NAME)
|
||||
.field(STRING_FIELD_NAME_2)
|
||||
.analyzer("stop")
|
||||
)
|
||||
.toQuery(createShardContext());
|
||||
assertEquals(expected, query);
|
||||
}
|
||||
|
||||
public void testWithPrefixStopWords() throws Exception {
|
||||
|
|
|
@ -613,11 +613,59 @@ public class SimpleQueryStringBuilderTests extends AbstractQueryTestCase<SimpleQ
|
|||
.field(STRING_FIELD_NAME)
|
||||
.analyzer("stop")
|
||||
.toQuery(createShardContext());
|
||||
BooleanQuery expected = new BooleanQuery.Builder()
|
||||
Query expected = new BooleanQuery.Builder()
|
||||
.add(new TermQuery(new Term(STRING_FIELD_NAME, "quick")), BooleanClause.Occur.SHOULD)
|
||||
.add(new TermQuery(new Term(STRING_FIELD_NAME, "fox")), BooleanClause.Occur.SHOULD)
|
||||
.build();
|
||||
assertEquals(expected, query);
|
||||
|
||||
query = new SimpleQueryStringBuilder("the quick fox")
|
||||
.field(STRING_FIELD_NAME)
|
||||
.field(STRING_FIELD_NAME_2)
|
||||
.analyzer("stop")
|
||||
.toQuery(createShardContext());
|
||||
expected = new BooleanQuery.Builder()
|
||||
.add(new DisjunctionMaxQuery(
|
||||
Arrays.asList(
|
||||
new TermQuery(new Term(STRING_FIELD_NAME, "quick")),
|
||||
new TermQuery(new Term(STRING_FIELD_NAME_2, "quick"))
|
||||
), 1.0f), BooleanClause.Occur.SHOULD)
|
||||
.add(new DisjunctionMaxQuery(
|
||||
Arrays.asList(
|
||||
new TermQuery(new Term(STRING_FIELD_NAME, "fox")),
|
||||
new TermQuery(new Term(STRING_FIELD_NAME_2, "fox"))
|
||||
), 1.0f), BooleanClause.Occur.SHOULD)
|
||||
.build();
|
||||
assertEquals(expected, query);
|
||||
|
||||
query = new SimpleQueryStringBuilder("the")
|
||||
.field(STRING_FIELD_NAME)
|
||||
.field(STRING_FIELD_NAME_2)
|
||||
.analyzer("stop")
|
||||
.toQuery(createShardContext());
|
||||
assertEquals(new MatchNoDocsQuery(), query);
|
||||
|
||||
query = new BoolQueryBuilder()
|
||||
.should(
|
||||
new SimpleQueryStringBuilder("the")
|
||||
.field(STRING_FIELD_NAME)
|
||||
.analyzer("stop")
|
||||
)
|
||||
.toQuery(createShardContext());
|
||||
expected = new BooleanQuery.Builder()
|
||||
.add(new MatchNoDocsQuery(), BooleanClause.Occur.SHOULD)
|
||||
.build();
|
||||
assertEquals(expected, query);
|
||||
|
||||
query = new BoolQueryBuilder()
|
||||
.should(
|
||||
new SimpleQueryStringBuilder("the")
|
||||
.field(STRING_FIELD_NAME)
|
||||
.field(STRING_FIELD_NAME_2)
|
||||
.analyzer("stop")
|
||||
)
|
||||
.toQuery(createShardContext());
|
||||
assertEquals(expected, query);
|
||||
}
|
||||
|
||||
public void testWithPrefixStopWords() throws Exception {
|
||||
|
|
Loading…
Reference in New Issue