Fix exists query on unmapped field in query_string (#58804)
Since #55785, exists queries rewrite to MatchNoneQueryBuilder when the field is unmapped. This change also introduced a bug in the `query_string` query, using an unmapped field like `_exists_:foo` throws an exception if the field is unmapped. This commit avoids the exception if the query is built outside of an `ExistsQueryBuilder`. Closes #58737
This commit is contained in:
parent
605e24ed7c
commit
a4e08acdd1
|
@ -24,6 +24,7 @@ import org.apache.lucene.search.BooleanClause;
|
|||
import org.apache.lucene.search.BooleanClause.Occur;
|
||||
import org.apache.lucene.search.BooleanQuery;
|
||||
import org.apache.lucene.search.ConstantScoreQuery;
|
||||
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.elasticsearch.Version;
|
||||
|
@ -139,15 +140,19 @@ public class ExistsQueryBuilder extends AbstractQueryBuilder<ExistsQueryBuilder>
|
|||
|
||||
@Override
|
||||
protected Query doToQuery(QueryShardContext context) throws IOException {
|
||||
return newFilter(context, fieldName);
|
||||
return newFilter(context, fieldName, true);
|
||||
}
|
||||
|
||||
public static Query newFilter(QueryShardContext context, String fieldPattern) {
|
||||
public static Query newFilter(QueryShardContext context, String fieldPattern, boolean checkRewrite) {
|
||||
|
||||
Collection<String> fields = getMappedField(context, fieldPattern);
|
||||
|
||||
if (fields.isEmpty()) {
|
||||
throw new IllegalStateException("Rewrite first");
|
||||
if (checkRewrite) {
|
||||
throw new IllegalStateException("Rewrite first");
|
||||
} else {
|
||||
return new MatchNoDocsQuery("unmapped field:" + fieldPattern);
|
||||
}
|
||||
}
|
||||
|
||||
if (context.indexVersionCreated().before(Version.V_6_1_0)) {
|
||||
|
|
|
@ -94,7 +94,7 @@ public class LegacyGeoShapeQueryProcessor implements QueryProcessor {
|
|||
// before, including creating lucene fieldcache (!)
|
||||
// in this case, execute disjoint as exists && !intersects
|
||||
BooleanQuery.Builder bool = new BooleanQuery.Builder();
|
||||
Query exists = ExistsQueryBuilder.newFilter(context, fieldName);
|
||||
Query exists = ExistsQueryBuilder.newFilter(context, fieldName,false);
|
||||
Query intersects = prefixTreeStrategy.makeQuery(getArgs(shape, ShapeRelation.INTERSECTS));
|
||||
bool.add(exists, BooleanClause.Occur.MUST);
|
||||
bool.add(intersects, BooleanClause.Occur.MUST_NOT);
|
||||
|
|
|
@ -486,7 +486,7 @@ public class RangeQueryBuilder extends AbstractQueryBuilder<RangeQueryBuilder> i
|
|||
}
|
||||
// Exists query would fail if the fieldNames field is disabled.
|
||||
if (fieldNamesFieldType.isEnabled()) {
|
||||
return ExistsQueryBuilder.newFilter(context, fieldName);
|
||||
return ExistsQueryBuilder.newFilter(context, fieldName, false);
|
||||
}
|
||||
}
|
||||
MappedFieldType mapper = context.fieldMapper(this.fieldName);
|
||||
|
|
|
@ -632,7 +632,7 @@ public class QueryStringQueryParser extends XQueryParser {
|
|||
return new WildcardQuery(new Term(fieldName, "*"));
|
||||
}
|
||||
|
||||
return ExistsQueryBuilder.newFilter(context, fieldName);
|
||||
return ExistsQueryBuilder.newFilter(context, fieldName, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -134,6 +134,8 @@ public class ExistsQueryBuilderTests extends AbstractQueryTestCase<ExistsQueryBu
|
|||
IllegalStateException e = expectThrows(IllegalStateException.class,
|
||||
() -> queryBuilder.toQuery(context));
|
||||
assertEquals("Rewrite first", e.getMessage());
|
||||
Query ret = ExistsQueryBuilder.newFilter(context, "foo", false);
|
||||
assertThat(ret, instanceOf(MatchNoDocsQuery.class));
|
||||
}
|
||||
|
||||
public void testIllegalArguments() {
|
||||
|
|
Loading…
Reference in New Issue