Handle specialized term queries in MappedFieldType.extractTerm(TermQuery) (#21889)
For some fields we have a specialized implementation of a TermQuery that is specific for the field. When these kind of fields are used in a wildcard query or a span term query it fails with an exception because they don't recognize the specialized form. The impacted fields are [_all] and [_type] and the impacted queries are [span_term] and [wilcard]. This change handles these forms and correctly extracts the term inside them for further use. Fixes #21882
This commit is contained in:
parent
92f05e796e
commit
fc9b63877e
|
@ -19,7 +19,6 @@
|
|||
|
||||
package org.elasticsearch.index.mapper;
|
||||
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.index.IndexOptions;
|
||||
import org.apache.lucene.index.IndexableField;
|
||||
import org.apache.lucene.index.Term;
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.apache.lucene.search.BoostQuery;
|
|||
import org.elasticsearch.action.fieldstats.FieldStats;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.joda.DateMathParser;
|
||||
import org.elasticsearch.common.lucene.all.AllTermQuery;
|
||||
import org.elasticsearch.common.unit.Fuzziness;
|
||||
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||
|
@ -463,6 +464,12 @@ public abstract class MappedFieldType extends FieldType {
|
|||
while (termQuery instanceof BoostQuery) {
|
||||
termQuery = ((BoostQuery) termQuery).getQuery();
|
||||
}
|
||||
if (termQuery instanceof AllTermQuery) {
|
||||
return ((AllTermQuery) termQuery).getTerm();
|
||||
} else if (termQuery instanceof TypeFieldMapper.TypesQuery) {
|
||||
assert ((TypeFieldMapper.TypesQuery) termQuery).getTerms().length == 1;
|
||||
return new Term(TypeFieldMapper.NAME, ((TypeFieldMapper.TypesQuery) termQuery).getTerms()[0]);
|
||||
}
|
||||
if (termQuery instanceof TermQuery == false) {
|
||||
throw new IllegalArgumentException("Cannot extract a term from a query of type "
|
||||
+ termQuery.getClass() + ": " + termQuery);
|
||||
|
|
|
@ -186,6 +186,10 @@ public class TypeFieldMapper extends MetadataFieldMapper {
|
|||
this.types = types;
|
||||
}
|
||||
|
||||
public BytesRef[] getTerms() {
|
||||
return types;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query rewrite(IndexReader reader) throws IOException {
|
||||
final int threshold = Math.min(BOOLEAN_REWRITE_TERM_COUNT_THRESHOLD, BooleanQuery.getMaxClauseCount());
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
package org.elasticsearch.index.query;
|
||||
|
||||
import com.fasterxml.jackson.core.io.JsonStringEncoder;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
|
@ -26,8 +27,6 @@ import org.apache.lucene.search.spans.SpanTermQuery;
|
|||
import org.elasticsearch.common.ParsingException;
|
||||
import org.elasticsearch.common.lucene.BytesRefs;
|
||||
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||
|
||||
import com.fasterxml.jackson.core.io.JsonStringEncoder;
|
||||
import org.elasticsearch.search.internal.SearchContext;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -132,4 +131,13 @@ public class SpanTermQueryBuilderTests extends AbstractTermQueryTestCase<SpanTer
|
|||
assertEquals("[span_term] query doesn't support multiple fields, found [message1] and [message2]", e.getMessage());
|
||||
}
|
||||
|
||||
public void testWithMetaDataField() throws IOException {
|
||||
QueryShardContext context = createShardContext();
|
||||
for (String field : new String[]{"_type", "_all"}) {
|
||||
SpanTermQueryBuilder spanTermQueryBuilder = new SpanTermQueryBuilder(field, "toto");
|
||||
Query query = spanTermQueryBuilder.toQuery(context);
|
||||
Query expected = new SpanTermQuery(new Term(field, "toto"));
|
||||
assertEquals(expected, query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
package org.elasticsearch.index.query;
|
||||
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.WildcardQuery;
|
||||
import org.elasticsearch.common.ParsingException;
|
||||
|
@ -125,4 +126,14 @@ public class WildcardQueryBuilderTests extends AbstractQueryTestCase<WildcardQue
|
|||
e = expectThrows(ParsingException.class, () -> parseQuery(shortJson));
|
||||
assertEquals("[wildcard] query doesn't support multiple fields, found [user1] and [user2]", e.getMessage());
|
||||
}
|
||||
|
||||
public void testWithMetaDataField() throws IOException {
|
||||
QueryShardContext context = createShardContext();
|
||||
for (String field : new String[]{"_type", "_all"}) {
|
||||
WildcardQueryBuilder wildcardQueryBuilder = new WildcardQueryBuilder(field, "toto");
|
||||
Query query = wildcardQueryBuilder.toQuery(context);
|
||||
Query expected = new WildcardQuery(new Term(field, "toto"));
|
||||
assertEquals(expected, query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue