Skip to content

Commit 1a95cc3

Browse files
committed
Fix UOE when building exists query for nested search-as-you-type field (#64630)
PrefixFieldType can use the default existsQuery() implementation. Fixes #64609
1 parent 254d1ba commit 1a95cc3

File tree

3 files changed

+36
-5
lines changed

3 files changed

+36
-5
lines changed

modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/SearchAsYouTypeFieldMapper.java

-5
Original file line numberDiff line numberDiff line change
@@ -394,11 +394,6 @@ public String typeName() {
394394
public String toString() {
395395
return super.toString() + ",prefixChars=" + minChars + ":" + maxChars;
396396
}
397-
398-
@Override
399-
public Query existsQuery(QueryShardContext context) {
400-
throw new UnsupportedOperationException();
401-
}
402397
}
403398

404399
static final class PrefixFieldMapper extends FieldMapper {

modules/mapper-extras/src/test/java/org/elasticsearch/index/mapper/SearchAsYouTypeFieldMapperTests.java

+34
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,21 @@
2626
import org.apache.lucene.index.IndexableField;
2727
import org.apache.lucene.index.IndexableFieldType;
2828
import org.apache.lucene.index.Term;
29+
import org.apache.lucene.queryparser.classic.ParseException;
2930
import org.apache.lucene.search.BooleanClause;
3031
import org.apache.lucene.search.BooleanQuery;
3132
import org.apache.lucene.search.ConstantScoreQuery;
3233
import org.apache.lucene.search.DisjunctionMaxQuery;
3334
import org.apache.lucene.search.MatchNoDocsQuery;
3435
import org.apache.lucene.search.MultiPhraseQuery;
36+
import org.apache.lucene.search.NormsFieldExistsQuery;
3537
import org.apache.lucene.search.Query;
3638
import org.apache.lucene.search.SynonymQuery;
3739
import org.apache.lucene.search.TermQuery;
3840
import org.apache.lucene.search.spans.FieldMaskingSpanQuery;
3941
import org.apache.lucene.search.spans.SpanNearQuery;
4042
import org.apache.lucene.search.spans.SpanTermQuery;
43+
import org.elasticsearch.Version;
4144
import org.elasticsearch.common.lucene.search.MultiPhrasePrefixQuery;
4245
import org.elasticsearch.common.xcontent.XContentBuilder;
4346
import org.elasticsearch.index.IndexSettings;
@@ -54,6 +57,7 @@
5457
import org.elasticsearch.index.query.MatchPhraseQueryBuilder;
5558
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
5659
import org.elasticsearch.index.query.QueryShardContext;
60+
import org.elasticsearch.index.search.QueryStringQueryParser;
5761
import org.elasticsearch.plugins.Plugin;
5862

5963
import java.io.IOException;
@@ -74,6 +78,7 @@
7478
import static org.hamcrest.Matchers.hasSize;
7579
import static org.hamcrest.Matchers.notNullValue;
7680
import static org.hamcrest.core.IsInstanceOf.instanceOf;
81+
import static org.mockito.Mockito.when;
7782

7883
public class SearchAsYouTypeFieldMapperTests extends MapperTestCase {
7984

@@ -534,6 +539,35 @@ public void testMatchPhrase() throws IOException {
534539
}
535540
}
536541

542+
public void testNestedExistsQuery() throws IOException, ParseException {
543+
MapperService ms = createMapperService(mapping(b -> {
544+
b.startObject("foo");
545+
{
546+
b.field("type", "object");
547+
b.startObject("properties");
548+
{
549+
b.startObject("bar");
550+
{
551+
b.field("type", "search_as_you_type");
552+
}
553+
b.endObject();
554+
}
555+
b.endObject();
556+
}
557+
b.endObject();
558+
}));
559+
QueryShardContext qsc = createQueryShardContext(ms);
560+
when(qsc.indexVersionCreated()).thenReturn(Version.CURRENT);
561+
QueryStringQueryParser parser = new QueryStringQueryParser(qsc, "f");
562+
Query q = parser.parse("foo:*");
563+
assertEquals(new ConstantScoreQuery(new BooleanQuery.Builder()
564+
.add(new NormsFieldExistsQuery("foo.bar"), BooleanClause.Occur.SHOULD)
565+
.add(new NormsFieldExistsQuery("foo.bar._3gram"), BooleanClause.Occur.SHOULD)
566+
.add(new NormsFieldExistsQuery("foo.bar._2gram"), BooleanClause.Occur.SHOULD)
567+
.add(new TermQuery(new Term("_field_names", "foo.bar._index_prefix")), BooleanClause.Occur.SHOULD)
568+
.build()), q);
569+
}
570+
537571
private static BooleanQuery buildBoolPrefixQuery(String shingleFieldName, String prefixFieldName, List<String> terms) {
538572
final BooleanQuery.Builder builder = new BooleanQuery.Builder();
539573
for (int i = 0; i < terms.size() - 1; i++) {

test/framework/src/main/java/org/elasticsearch/index/mapper/MapperServiceTestCase.java

+2
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,8 @@ protected QueryShardContext createQueryShardContext(MapperService mapperService)
401401
.thenAnswer(inv -> mapperService.fieldType(inv.getArguments()[0].toString()) != null);
402402
when(queryShardContext.getIndexAnalyzers()).thenReturn(mapperService.getIndexAnalyzers());
403403
when(queryShardContext.getIndexSettings()).thenReturn(mapperService.getIndexSettings());
404+
when(queryShardContext.getObjectMapper(anyString())).thenAnswer(
405+
inv -> mapperService.getObjectMapper(inv.getArguments()[0].toString()));
404406
when(queryShardContext.simpleMatchToIndexNames(anyObject())).thenAnswer(
405407
inv -> mapperService.simpleMatchToFullName(inv.getArguments()[0].toString())
406408
);

0 commit comments

Comments
 (0)