Full text queries should not always ignore unmapped fields (#41062)
Full text queries ignore unmapped fields since https://github.com/elastic/elasticsearch/issues/41022 even if all fields in the query are unmapped. This change makes sure that we ignore unmapped fields only if they are mixed with mapped fields and returns a MatchNoDocsQuery otherwise. Closes #41022
This commit is contained in:
parent
fe9442b05b
commit
d30fec4914
|
@ -36,6 +36,8 @@ import org.elasticsearch.common.Nullable;
|
|||
import org.elasticsearch.index.mapper.SeqNoFieldMapper;
|
||||
import org.elasticsearch.index.mapper.TypeFieldMapper;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -52,7 +54,11 @@ public class Queries {
|
|||
|
||||
|
||||
public static Query newUnmappedFieldQuery(String field) {
|
||||
return Queries.newMatchNoDocsQuery("unmapped field [" + (field != null ? field : "null") + "]");
|
||||
return newUnmappedFieldsQuery(Collections.singletonList(field));
|
||||
}
|
||||
|
||||
public static Query newUnmappedFieldsQuery(Collection<String> fields) {
|
||||
return Queries.newMatchNoDocsQuery("unmapped fields " + fields);
|
||||
}
|
||||
|
||||
public static Query newLenientFieldQuery(String field, RuntimeException e) {
|
||||
|
|
|
@ -59,6 +59,12 @@ public class MultiMatchQuery extends MatchQuery {
|
|||
|
||||
public Query parse(MultiMatchQueryBuilder.Type type, Map<String, Float> fieldNames,
|
||||
Object value, String minimumShouldMatch) throws IOException {
|
||||
boolean hasMappedField = fieldNames.keySet().stream()
|
||||
.anyMatch(k -> context.fieldMapper(k) != null);
|
||||
if (hasMappedField == false) {
|
||||
// all query fields are unmapped
|
||||
return Queries.newUnmappedFieldsQuery(fieldNames.keySet());
|
||||
}
|
||||
final float tieBreaker = groupTieBreaker == null ? type.tieBreaker() : groupTieBreaker;
|
||||
final List<Query> queries;
|
||||
switch (type) {
|
||||
|
@ -91,7 +97,7 @@ public class MultiMatchQuery extends MatchQuery {
|
|||
}
|
||||
|
||||
private List<Query> buildFieldQueries(MultiMatchQueryBuilder.Type type, Map<String, Float> fieldNames,
|
||||
Object value, String minimumShouldMatch) throws IOException{
|
||||
Object value, String minimumShouldMatch) throws IOException {
|
||||
List<Query> queries = new ArrayList<>();
|
||||
for (String fieldName : fieldNames.keySet()) {
|
||||
if (context.fieldMapper(fieldName) == null) {
|
||||
|
|
|
@ -1210,13 +1210,13 @@ public class QueryStringQueryBuilderTests extends AbstractQueryTestCase<QueryStr
|
|||
.field("unmapped_field")
|
||||
.lenient(true)
|
||||
.toQuery(createShardContext());
|
||||
assertEquals(new BooleanQuery.Builder().build(), query);
|
||||
assertEquals(new MatchNoDocsQuery(), query);
|
||||
|
||||
// Unmapped prefix field
|
||||
query = new QueryStringQueryBuilder("unmapped_field:hello")
|
||||
.lenient(true)
|
||||
.toQuery(createShardContext());
|
||||
assertEquals(new BooleanQuery.Builder().build(), query);
|
||||
assertEquals(new MatchNoDocsQuery(), query);
|
||||
|
||||
// Unmapped fields
|
||||
query = new QueryStringQueryBuilder("hello")
|
||||
|
@ -1224,7 +1224,32 @@ public class QueryStringQueryBuilderTests extends AbstractQueryTestCase<QueryStr
|
|||
.field("unmapped_field")
|
||||
.field("another_field")
|
||||
.toQuery(createShardContext());
|
||||
assertEquals(new BooleanQuery.Builder().build(), query);
|
||||
assertEquals(new MatchNoDocsQuery(), query);
|
||||
|
||||
// Multi block
|
||||
query = new QueryStringQueryBuilder("first unmapped:second")
|
||||
.field(STRING_FIELD_NAME)
|
||||
.field("unmapped")
|
||||
.field("another_unmapped")
|
||||
.defaultOperator(Operator.AND)
|
||||
.toQuery(createShardContext());
|
||||
BooleanQuery expected = new BooleanQuery.Builder()
|
||||
.add(new TermQuery(new Term(STRING_FIELD_NAME, "first")), BooleanClause.Occur.MUST)
|
||||
.add(new MatchNoDocsQuery(), BooleanClause.Occur.MUST)
|
||||
.build();
|
||||
assertEquals(expected, query);
|
||||
|
||||
query = new SimpleQueryStringBuilder("first unknown:second")
|
||||
.field("unmapped")
|
||||
.field("another_unmapped")
|
||||
.defaultOperator(Operator.AND)
|
||||
.toQuery(createShardContext());
|
||||
expected = new BooleanQuery.Builder()
|
||||
.add(new MatchNoDocsQuery(), BooleanClause.Occur.MUST)
|
||||
.add(new MatchNoDocsQuery(), BooleanClause.Occur.MUST)
|
||||
.build();
|
||||
assertEquals(expected, query);
|
||||
|
||||
}
|
||||
|
||||
public void testDefaultField() throws Exception {
|
||||
|
|
|
@ -717,6 +717,17 @@ public class SimpleQueryStringBuilderTests extends AbstractQueryTestCase<SimpleQ
|
|||
.add(new TermQuery(new Term(STRING_FIELD_NAME, "second")), BooleanClause.Occur.MUST)
|
||||
.build();
|
||||
assertEquals(expected, query);
|
||||
query = new SimpleQueryStringBuilder("first & second")
|
||||
.field("unmapped")
|
||||
.field("another_unmapped")
|
||||
.defaultOperator(Operator.AND)
|
||||
.toQuery(createShardContext());
|
||||
expected = new BooleanQuery.Builder()
|
||||
.add(new MatchNoDocsQuery(), BooleanClause.Occur.MUST)
|
||||
.add(new MatchNoDocsQuery(), BooleanClause.Occur.MUST)
|
||||
.add(new MatchNoDocsQuery(), BooleanClause.Occur.MUST)
|
||||
.build();
|
||||
assertEquals(expected, query);
|
||||
}
|
||||
|
||||
public void testNegativeFieldBoost() {
|
||||
|
|
Loading…
Reference in New Issue