Skip to content

Commit 073ae88

Browse files
committed
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
1 parent e40d5af commit 073ae88

File tree

5 files changed

+32
-3
lines changed

5 files changed

+32
-3
lines changed

core/src/main/java/org/elasticsearch/index/mapper/AllFieldMapper.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
package org.elasticsearch.index.mapper;
2121

22-
import org.apache.lucene.document.Field;
2322
import org.apache.lucene.index.IndexOptions;
2423
import org.apache.lucene.index.IndexableField;
2524
import org.apache.lucene.index.Term;

core/src/main/java/org/elasticsearch/index/mapper/MappedFieldType.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.elasticsearch.action.fieldstats.FieldStats;
3636
import org.elasticsearch.common.Nullable;
3737
import org.elasticsearch.common.joda.DateMathParser;
38+
import org.elasticsearch.common.lucene.all.AllTermQuery;
3839
import org.elasticsearch.common.unit.Fuzziness;
3940
import org.elasticsearch.index.analysis.NamedAnalyzer;
4041
import org.elasticsearch.index.fielddata.IndexFieldData;
@@ -463,6 +464,12 @@ public static Term extractTerm(Query termQuery) {
463464
while (termQuery instanceof BoostQuery) {
464465
termQuery = ((BoostQuery) termQuery).getQuery();
465466
}
467+
if (termQuery instanceof AllTermQuery) {
468+
return ((AllTermQuery) termQuery).getTerm();
469+
} else if (termQuery instanceof TypeFieldMapper.TypesQuery) {
470+
assert ((TypeFieldMapper.TypesQuery) termQuery).getTerms().length == 1;
471+
return new Term(TypeFieldMapper.NAME, ((TypeFieldMapper.TypesQuery) termQuery).getTerms()[0]);
472+
}
466473
if (termQuery instanceof TermQuery == false) {
467474
throw new IllegalArgumentException("Cannot extract a term from a query of type "
468475
+ termQuery.getClass() + ": " + termQuery);

core/src/main/java/org/elasticsearch/index/mapper/TypeFieldMapper.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,10 @@ public TypesQuery(BytesRef... types) {
190190
this.types = types;
191191
}
192192

193+
public BytesRef[] getTerms() {
194+
return types;
195+
}
196+
193197
@Override
194198
public Query rewrite(IndexReader reader) throws IOException {
195199
final int threshold = Math.min(BOOLEAN_REWRITE_TERM_COUNT_THRESHOLD, BooleanQuery.getMaxClauseCount());

core/src/test/java/org/elasticsearch/index/query/SpanTermQueryBuilderTests.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,14 @@
1919

2020
package org.elasticsearch.index.query;
2121

22+
import com.fasterxml.jackson.core.io.JsonStringEncoder;
2223
import org.apache.lucene.index.Term;
2324
import org.apache.lucene.search.Query;
2425
import org.apache.lucene.search.TermQuery;
2526
import org.apache.lucene.search.spans.SpanTermQuery;
2627
import org.elasticsearch.common.ParsingException;
2728
import org.elasticsearch.common.lucene.BytesRefs;
2829
import org.elasticsearch.index.mapper.MappedFieldType;
29-
30-
import com.fasterxml.jackson.core.io.JsonStringEncoder;
3130
import org.elasticsearch.search.internal.SearchContext;
3231

3332
import java.io.IOException;
@@ -132,4 +131,13 @@ public void testParseFailsWithMultipleFields() throws IOException {
132131
assertEquals("[span_term] query doesn't support multiple fields, found [message1] and [message2]", e.getMessage());
133132
}
134133

134+
public void testWithMetaDataField() throws IOException {
135+
QueryShardContext context = createShardContext();
136+
for (String field : new String[]{"_type", "_all"}) {
137+
SpanTermQueryBuilder spanTermQueryBuilder = new SpanTermQueryBuilder(field, "toto");
138+
Query query = spanTermQueryBuilder.toQuery(context);
139+
Query expected = new SpanTermQuery(new Term(field, "toto"));
140+
assertEquals(expected, query);
141+
}
142+
}
135143
}

core/src/test/java/org/elasticsearch/index/query/WildcardQueryBuilderTests.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
package org.elasticsearch.index.query;
2121

22+
import org.apache.lucene.index.Term;
2223
import org.apache.lucene.search.Query;
2324
import org.apache.lucene.search.WildcardQuery;
2425
import org.elasticsearch.common.ParsingException;
@@ -125,4 +126,14 @@ public void testParseFailsWithMultipleFields() throws IOException {
125126
e = expectThrows(ParsingException.class, () -> parseQuery(shortJson));
126127
assertEquals("[wildcard] query doesn't support multiple fields, found [user1] and [user2]", e.getMessage());
127128
}
129+
130+
public void testWithMetaDataField() throws IOException {
131+
QueryShardContext context = createShardContext();
132+
for (String field : new String[]{"_type", "_all"}) {
133+
WildcardQueryBuilder wildcardQueryBuilder = new WildcardQueryBuilder(field, "toto");
134+
Query query = wildcardQueryBuilder.toQuery(context);
135+
Query expected = new WildcardQuery(new Term(field, "toto"));
136+
assertEquals(expected, query);
137+
}
138+
}
128139
}

0 commit comments

Comments
 (0)