Skip to content

Commit

Permalink
When creating wildcard queries, use MatchNoDocsQuery when the field t…
Browse files Browse the repository at this point in the history
…ype doesn't exist. (#34093)
  • Loading branch information
jtibshirani committed Sep 28, 2018
1 parent 161f480 commit 9454c6a
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.Version;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.lucene.Lucene;
import org.elasticsearch.common.settings.Settings;
Expand Down Expand Up @@ -177,7 +178,9 @@ public Query prefixQuery(String value, MultiTermQuery.RewriteMethod method, Quer
}

@Override
public Query wildcardQuery(String value, QueryShardContext context) {
public Query wildcardQuery(String value,
@Nullable MultiTermQuery.RewriteMethod method,
QueryShardContext context) {
throw new UnsupportedOperationException("[wildcard] queries are not supported on [" + CONTENT_TYPE + "] fields.");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public void testWildcardQuery() {
ft.setName("field");
ft.setIndexOptions(IndexOptions.DOCS);
expectThrows(UnsupportedOperationException.class,
() -> ft.wildcardQuery("foo*", null));
() -> ft.wildcardQuery("foo*", null, null));
}

public void testRangeQuery() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.apache.lucene.index.IndexOptions;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.Version;
Expand Down Expand Up @@ -155,7 +156,9 @@ public Query termsQuery(List values, QueryShardContext context) {
}

@Override
public Query wildcardQuery(String value, QueryShardContext context) {
public Query wildcardQuery(String value,
@Nullable MultiTermQuery.RewriteMethod method,
QueryShardContext context) {
if (isSameIndex(value, context.getFullyQualifiedIndex().getName())) {
return Queries.newMatchAllQuery();
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,9 @@ public Query prefixQuery(String value, @Nullable MultiTermQuery.RewriteMethod me
throw new QueryShardException(context, "Can only use prefix queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]");
}

public Query wildcardQuery(String value, QueryShardContext context) {
public Query wildcardQuery(String value,
@Nullable MultiTermQuery.RewriteMethod method,
QueryShardContext context) {
throw new QueryShardException(context, "Can only use wildcard queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.elasticsearch.common.lucene.BytesRefs;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.index.query.support.QueryParsers;

import java.io.IOException;
import java.util.ArrayList;
Expand Down Expand Up @@ -85,13 +86,16 @@ public Query prefixQuery(String value, MultiTermQuery.RewriteMethod method, Quer
}

@Override
public Query wildcardQuery(String value, QueryShardContext context) {
public Query wildcardQuery(String value, MultiTermQuery.RewriteMethod method, QueryShardContext context) {
Query termQuery = termQuery(value, context);
if (termQuery instanceof MatchNoDocsQuery || termQuery instanceof MatchAllDocsQuery) {
return termQuery;
}
Term term = MappedFieldType.extractTerm(termQuery);
return new WildcardQuery(term);

WildcardQuery query = new WildcardQuery(term);
QueryParsers.setRewriteMethod(query, method);
return query;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,14 @@

package org.elasticsearch.index.query;

import org.apache.lucene.index.Term;
import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.WildcardQuery;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.lucene.BytesRefs;
import org.elasticsearch.common.xcontent.LoggingDeprecationHandler;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
Expand Down Expand Up @@ -185,20 +183,13 @@ public static WildcardQueryBuilder fromXContent(XContentParser parser) throws IO
protected Query doToQuery(QueryShardContext context) throws IOException {
MappedFieldType fieldType = context.fieldMapper(fieldName);

Query query;
if (fieldType == null) {
Term term = new Term(fieldName, BytesRefs.toBytesRef(value));
query = new WildcardQuery(term);
} else {
query = fieldType.wildcardQuery(value, context);
return new MatchNoDocsQuery("unknown field [" + fieldName + "]");
}

if (query instanceof MultiTermQuery) {
MultiTermQuery.RewriteMethod rewriteMethod = QueryParsers.parseRewriteMethod(
rewrite, null, LoggingDeprecationHandler.INSTANCE);
QueryParsers.setRewriteMethod((MultiTermQuery) query, rewriteMethod);
}
return query;
MultiTermQuery.RewriteMethod method = QueryParsers.parseRewriteMethod(
rewrite, null, LoggingDeprecationHandler.INSTANCE);
return fieldType.wildcardQuery(value, method, context);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

package org.elasticsearch.index.query;

import org.apache.lucene.index.Term;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
Expand Down Expand Up @@ -70,13 +69,19 @@ private static WildcardQueryBuilder randomWildcardQuery() {

@Override
protected void doAssertLuceneQuery(WildcardQueryBuilder queryBuilder, Query query, SearchContext context) throws IOException {
assertThat(query, instanceOf(WildcardQuery.class));
WildcardQuery wildcardQuery = (WildcardQuery) query;

String expectedFieldName = expectedFieldName(queryBuilder.fieldName());
assertThat(wildcardQuery.getField(), equalTo(expectedFieldName));
assertThat(wildcardQuery.getTerm().field(), equalTo(expectedFieldName));
assertThat(wildcardQuery.getTerm().text(), equalTo(queryBuilder.value()));

if (expectedFieldName.equals(STRING_FIELD_NAME)) {
assertThat(query, instanceOf(WildcardQuery.class));
WildcardQuery wildcardQuery = (WildcardQuery) query;

assertThat(wildcardQuery.getField(), equalTo(expectedFieldName));
assertThat(wildcardQuery.getTerm().field(), equalTo(expectedFieldName));
assertThat(wildcardQuery.getTerm().text(), equalTo(queryBuilder.value()));
} else {
Query expected = new MatchNoDocsQuery("unknown field [" + expectedFieldName + "]");
assertEquals(expected, query);
}
}

public void testIllegalArguments() {
Expand All @@ -92,7 +97,7 @@ public void testIllegalArguments() {
public void testEmptyValue() throws IOException {
QueryShardContext context = createShardContext();
context.setAllowUnmappedFields(true);
WildcardQueryBuilder wildcardQueryBuilder = new WildcardQueryBuilder("doc", "");
WildcardQueryBuilder wildcardQueryBuilder = new WildcardQueryBuilder(STRING_FIELD_NAME, "");
assertEquals(wildcardQueryBuilder.toQuery(context).getClass(), WildcardQuery.class);
}

Expand Down Expand Up @@ -130,16 +135,6 @@ public void testParseFailsWithMultipleFields() throws IOException {
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[]{"field1", "field2"}) {
WildcardQueryBuilder wildcardQueryBuilder = new WildcardQueryBuilder(field, "toto");
Query query = wildcardQueryBuilder.toQuery(context);
Query expected = new WildcardQuery(new Term(field, "toto"));
assertEquals(expected, query);
}
}

public void testIndexWildcard() throws IOException {
assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);

Expand Down

0 comments on commit 9454c6a

Please sign in to comment.