Delegate wildcard query creation to MappedFieldType. (#34062)
* Delegate wildcard query creation to MappedFieldType. * Disallow wildcard queries on collation fields. * Disallow wildcard queries on non-string fields.
This commit is contained in:
parent
4fbe84edf6
commit
de8bfb908f
|
@ -23,7 +23,6 @@ import com.ibm.icu.text.Collator;
|
||||||
import com.ibm.icu.text.RawCollationKey;
|
import com.ibm.icu.text.RawCollationKey;
|
||||||
import com.ibm.icu.text.RuleBasedCollator;
|
import com.ibm.icu.text.RuleBasedCollator;
|
||||||
import com.ibm.icu.util.ULocale;
|
import com.ibm.icu.util.ULocale;
|
||||||
|
|
||||||
import org.apache.lucene.document.Field;
|
import org.apache.lucene.document.Field;
|
||||||
import org.apache.lucene.document.SortedSetDocValuesField;
|
import org.apache.lucene.document.SortedSetDocValuesField;
|
||||||
import org.apache.lucene.index.IndexOptions;
|
import org.apache.lucene.index.IndexOptions;
|
||||||
|
@ -159,18 +158,23 @@ public class ICUCollationKeywordFieldMapper extends FieldMapper {
|
||||||
@Override
|
@Override
|
||||||
public Query fuzzyQuery(Object value, Fuzziness fuzziness, int prefixLength, int maxExpansions,
|
public Query fuzzyQuery(Object value, Fuzziness fuzziness, int prefixLength, int maxExpansions,
|
||||||
boolean transpositions) {
|
boolean transpositions) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException("[fuzzy] queries are not supported on [" + CONTENT_TYPE + "] fields.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Query prefixQuery(String value, MultiTermQuery.RewriteMethod method, QueryShardContext context) {
|
public Query prefixQuery(String value, MultiTermQuery.RewriteMethod method, QueryShardContext context) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException("[prefix] queries are not supported on [" + CONTENT_TYPE + "] fields.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query wildcardQuery(String value, QueryShardContext context) {
|
||||||
|
throw new UnsupportedOperationException("[wildcard] queries are not supported on [" + CONTENT_TYPE + "] fields.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Query regexpQuery(String value, int flags, int maxDeterminizedStates,
|
public Query regexpQuery(String value, int flags, int maxDeterminizedStates,
|
||||||
MultiTermQuery.RewriteMethod method, QueryShardContext context) {
|
MultiTermQuery.RewriteMethod method, QueryShardContext context) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException("[regexp] queries are not supported on [" + CONTENT_TYPE + "] fields.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DocValueFormat COLLATE_FORMAT = new DocValueFormat() {
|
public static DocValueFormat COLLATE_FORMAT = new DocValueFormat() {
|
||||||
|
|
|
@ -121,6 +121,14 @@ public class CollationFieldTypeTests extends FieldTypeTestCase {
|
||||||
() -> ft.prefixQuery("prefix", null, null));
|
() -> ft.prefixQuery("prefix", null, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testWildcardQuery() {
|
||||||
|
MappedFieldType ft = createDefaultFieldType();
|
||||||
|
ft.setName("field");
|
||||||
|
ft.setIndexOptions(IndexOptions.DOCS);
|
||||||
|
expectThrows(UnsupportedOperationException.class,
|
||||||
|
() -> ft.wildcardQuery("foo*", null));
|
||||||
|
}
|
||||||
|
|
||||||
public void testRangeQuery() {
|
public void testRangeQuery() {
|
||||||
MappedFieldType ft = createDefaultFieldType();
|
MappedFieldType ft = createDefaultFieldType();
|
||||||
ft.setName("field");
|
ft.setName("field");
|
||||||
|
|
|
@ -150,8 +150,17 @@ public class IndexFieldMapper extends MetadataFieldMapper {
|
||||||
+ " vs. " + values);
|
+ " vs. " + values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query wildcardQuery(String value, QueryShardContext context) {
|
||||||
|
if (isSameIndex(value, context.getFullyQualifiedIndex().getName())) {
|
||||||
|
return Queries.newMatchAllQuery();
|
||||||
|
} else {
|
||||||
|
return Queries.newMatchNoDocsQuery("Index didn't match. Index queried: " + context.index().getName() + " vs. " + value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isSameIndex(Object value, String indexName) {
|
private boolean isSameIndex(Object value, String indexName) {
|
||||||
String pattern = value instanceof BytesRef ? pattern = ((BytesRef) value).utf8ToString() : value.toString();
|
String pattern = value instanceof BytesRef ? ((BytesRef) value).utf8ToString() : value.toString();
|
||||||
return Regex.simpleMatch(pattern, indexName);
|
return Regex.simpleMatch(pattern, indexName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -345,6 +345,10 @@ public abstract class MappedFieldType extends FieldType {
|
||||||
throw new QueryShardException(context, "Can only use prefix queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]");
|
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) {
|
||||||
|
throw new QueryShardException(context, "Can only use wildcard queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]");
|
||||||
|
}
|
||||||
|
|
||||||
public Query regexpQuery(String value, int flags, int maxDeterminizedStates, @Nullable MultiTermQuery.RewriteMethod method, QueryShardContext context) {
|
public Query regexpQuery(String value, int flags, int maxDeterminizedStates, @Nullable MultiTermQuery.RewriteMethod method, QueryShardContext context) {
|
||||||
throw new QueryShardException(context, "Can only use regexp queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]");
|
throw new QueryShardException(context, "Can only use regexp queries on keyword and text fields - not on [" + name + "] which is of type [" + typeName() + "]");
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,8 @@ package org.elasticsearch.index.mapper;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.lucene.index.Term;
|
import org.apache.lucene.index.Term;
|
||||||
|
import org.apache.lucene.search.MatchAllDocsQuery;
|
||||||
|
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||||
import org.apache.lucene.search.TermInSetQuery;
|
import org.apache.lucene.search.TermInSetQuery;
|
||||||
import org.apache.lucene.search.FuzzyQuery;
|
import org.apache.lucene.search.FuzzyQuery;
|
||||||
import org.apache.lucene.search.MultiTermQuery;
|
import org.apache.lucene.search.MultiTermQuery;
|
||||||
|
@ -29,6 +31,7 @@ import org.apache.lucene.search.PrefixQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.search.RegexpQuery;
|
import org.apache.lucene.search.RegexpQuery;
|
||||||
import org.apache.lucene.search.TermRangeQuery;
|
import org.apache.lucene.search.TermRangeQuery;
|
||||||
|
import org.apache.lucene.search.WildcardQuery;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
import org.elasticsearch.common.lucene.BytesRefs;
|
import org.elasticsearch.common.lucene.BytesRefs;
|
||||||
import org.elasticsearch.common.unit.Fuzziness;
|
import org.elasticsearch.common.unit.Fuzziness;
|
||||||
|
@ -74,6 +77,16 @@ public abstract class StringFieldType extends TermBasedFieldType {
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Query wildcardQuery(String value, 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);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Query regexpQuery(String value, int flags, int maxDeterminizedStates,
|
public Query regexpQuery(String value, int flags, int maxDeterminizedStates,
|
||||||
MultiTermQuery.RewriteMethod method, QueryShardContext context) {
|
MultiTermQuery.RewriteMethod method, QueryShardContext context) {
|
||||||
|
|
|
@ -20,8 +20,6 @@
|
||||||
package org.elasticsearch.index.query;
|
package org.elasticsearch.index.query;
|
||||||
|
|
||||||
import org.apache.lucene.index.Term;
|
import org.apache.lucene.index.Term;
|
||||||
import org.apache.lucene.search.MatchAllDocsQuery;
|
|
||||||
import org.apache.lucene.search.MatchNoDocsQuery;
|
|
||||||
import org.apache.lucene.search.MultiTermQuery;
|
import org.apache.lucene.search.MultiTermQuery;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.search.WildcardQuery;
|
import org.apache.lucene.search.WildcardQuery;
|
||||||
|
@ -185,20 +183,20 @@ public class WildcardQueryBuilder extends AbstractQueryBuilder<WildcardQueryBuil
|
||||||
@Override
|
@Override
|
||||||
protected Query doToQuery(QueryShardContext context) throws IOException {
|
protected Query doToQuery(QueryShardContext context) throws IOException {
|
||||||
MappedFieldType fieldType = context.fieldMapper(fieldName);
|
MappedFieldType fieldType = context.fieldMapper(fieldName);
|
||||||
Term term;
|
|
||||||
|
Query query;
|
||||||
if (fieldType == null) {
|
if (fieldType == null) {
|
||||||
term = new Term(fieldName, BytesRefs.toBytesRef(value));
|
Term term = new Term(fieldName, BytesRefs.toBytesRef(value));
|
||||||
|
query = new WildcardQuery(term);
|
||||||
} else {
|
} else {
|
||||||
Query termQuery = fieldType.termQuery(value, context);
|
query = fieldType.wildcardQuery(value, context);
|
||||||
if (termQuery instanceof MatchNoDocsQuery || termQuery instanceof MatchAllDocsQuery) {
|
|
||||||
return termQuery;
|
|
||||||
}
|
|
||||||
term = MappedFieldType.extractTerm(termQuery);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WildcardQuery query = new WildcardQuery(term);
|
if (query instanceof MultiTermQuery) {
|
||||||
MultiTermQuery.RewriteMethod rewriteMethod = QueryParsers.parseRewriteMethod(rewrite, null, LoggingDeprecationHandler.INSTANCE);
|
MultiTermQuery.RewriteMethod rewriteMethod = QueryParsers.parseRewriteMethod(
|
||||||
QueryParsers.setRewriteMethod(query, rewriteMethod);
|
rewrite, null, LoggingDeprecationHandler.INSTANCE);
|
||||||
|
QueryParsers.setRewriteMethod((MultiTermQuery) query, rewriteMethod);
|
||||||
|
}
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue