Support 'string'-style queries on metadata fields when reasonable. (#34089)
* Make sure 'ignored' and 'routing' field types inherit from StringFieldType. * Add tests for prefix and regexp queries. * Support prefix and regexp queries on _index fields.
This commit is contained in:
parent
33a264a408
commit
9cd4f70a67
|
@ -85,7 +85,7 @@ public final class IgnoredFieldMapper extends MetadataFieldMapper {
|
|||
}
|
||||
}
|
||||
|
||||
public static final class IgnoredFieldType extends TermBasedFieldType {
|
||||
public static final class IgnoredFieldType extends StringFieldType {
|
||||
|
||||
public IgnoredFieldType() {
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ import org.elasticsearch.index.query.QueryShardContext;
|
|||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
public class IndexFieldMapper extends MetadataFieldMapper {
|
||||
|
@ -151,14 +152,43 @@ public class IndexFieldMapper extends MetadataFieldMapper {
|
|||
+ " vs. " + values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query prefixQuery(String value,
|
||||
@Nullable MultiTermQuery.RewriteMethod method,
|
||||
QueryShardContext context) {
|
||||
String indexName = context.getFullyQualifiedIndex().getName();
|
||||
if (indexName.startsWith(value)) {
|
||||
return Queries.newMatchAllQuery();
|
||||
} else {
|
||||
return Queries.newMatchNoDocsQuery("The index [" + indexName +
|
||||
"] doesn't match the provided prefix [" + value + "].");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query regexpQuery(String value, int flags, int maxDeterminizedStates,
|
||||
MultiTermQuery.RewriteMethod method, QueryShardContext context) {
|
||||
String indexName = context.getFullyQualifiedIndex().getName();
|
||||
Pattern pattern = Regex.compile(value, Regex.flagsToString(flags));
|
||||
|
||||
if (pattern.matcher(indexName).matches()) {
|
||||
return Queries.newMatchAllQuery();
|
||||
} else {
|
||||
return Queries.newMatchNoDocsQuery("The index [" + indexName +
|
||||
"] doesn't match the provided pattern [" + value + "].");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query wildcardQuery(String value,
|
||||
@Nullable MultiTermQuery.RewriteMethod method,
|
||||
QueryShardContext context) {
|
||||
if (isSameIndex(value, context.getFullyQualifiedIndex().getName())) {
|
||||
String indexName = context.getFullyQualifiedIndex().getName();
|
||||
if (isSameIndex(value, indexName)) {
|
||||
return Queries.newMatchAllQuery();
|
||||
} else {
|
||||
return Queries.newMatchNoDocsQuery("Index didn't match. Index queried: " + context.index().getName() + " vs. " + value);
|
||||
return Queries.newMatchNoDocsQuery("The index [" + indexName +
|
||||
"] doesn't match the provided pattern [" + value + "].");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -108,7 +108,7 @@ public class RoutingFieldMapper extends MetadataFieldMapper {
|
|||
}
|
||||
}
|
||||
|
||||
static final class RoutingFieldType extends TermBasedFieldType {
|
||||
static final class RoutingFieldType extends StringFieldType {
|
||||
|
||||
RoutingFieldType() {
|
||||
}
|
||||
|
|
|
@ -19,6 +19,14 @@
|
|||
|
||||
package org.elasticsearch.index.mapper;
|
||||
|
||||
import org.apache.lucene.index.IndexOptions;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.PrefixQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.RegexpQuery;
|
||||
import org.apache.lucene.search.WildcardQuery;
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
|
||||
public class IgnoredFieldTypeTests extends FieldTypeTestCase {
|
||||
|
||||
@Override
|
||||
|
@ -26,4 +34,30 @@ public class IgnoredFieldTypeTests extends FieldTypeTestCase {
|
|||
return new IgnoredFieldMapper.IgnoredFieldType();
|
||||
}
|
||||
|
||||
public void testPrefixQuery() {
|
||||
MappedFieldType ft = createDefaultFieldType();
|
||||
ft.setName("field");
|
||||
ft.setIndexOptions(IndexOptions.DOCS);
|
||||
|
||||
Query expected = new PrefixQuery(new Term("field", new BytesRef("foo*")));
|
||||
assertEquals(expected, ft.prefixQuery("foo*", null, null));
|
||||
}
|
||||
|
||||
public void testRegexpQuery() {
|
||||
MappedFieldType ft = createDefaultFieldType();
|
||||
ft.setName("field");
|
||||
ft.setIndexOptions(IndexOptions.DOCS);
|
||||
|
||||
Query expected = new RegexpQuery(new Term("field", new BytesRef("foo?")));
|
||||
assertEquals(expected, ft.regexpQuery("foo?", 0, 10, null, null));
|
||||
}
|
||||
|
||||
public void testWildcardQuery() {
|
||||
MappedFieldType ft = createDefaultFieldType();
|
||||
ft.setName("field");
|
||||
ft.setIndexOptions(IndexOptions.DOCS);
|
||||
|
||||
Query expected = new WildcardQuery(new Term("field", new BytesRef("foo*")));
|
||||
assertEquals(expected, ft.wildcardQuery("foo*", null, null));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,12 +18,56 @@
|
|||
*/
|
||||
package org.elasticsearch.index.mapper;
|
||||
|
||||
import org.elasticsearch.index.mapper.IndexFieldMapper;
|
||||
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||
import org.apache.lucene.index.IndexOptions;
|
||||
import org.apache.lucene.search.MatchAllDocsQuery;
|
||||
import org.apache.lucene.search.MatchNoDocsQuery;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.query.QueryShardContext;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class IndexFieldTypeTests extends FieldTypeTestCase {
|
||||
|
||||
@Override
|
||||
protected MappedFieldType createDefaultFieldType() {
|
||||
return new IndexFieldMapper.IndexFieldType();
|
||||
}
|
||||
|
||||
public void testPrefixQuery() {
|
||||
MappedFieldType ft = createDefaultFieldType();
|
||||
ft.setName("field");
|
||||
ft.setIndexOptions(IndexOptions.DOCS);
|
||||
|
||||
assertEquals(new MatchAllDocsQuery(), ft.prefixQuery("ind", null, createContext()));
|
||||
assertEquals(new MatchNoDocsQuery(), ft.prefixQuery("other_ind", null, createContext()));
|
||||
}
|
||||
|
||||
public void testRegexpQuery() {
|
||||
MappedFieldType ft = createDefaultFieldType();
|
||||
ft.setName("field");
|
||||
ft.setIndexOptions(IndexOptions.DOCS);
|
||||
|
||||
assertEquals(new MatchAllDocsQuery(), ft.regexpQuery("ind.x", 0, 10, null, createContext()));
|
||||
assertEquals(new MatchNoDocsQuery(), ft.regexpQuery("ind?x", 0, 10, null, createContext()));
|
||||
}
|
||||
|
||||
public void testWildcardQuery() {
|
||||
MappedFieldType ft = createDefaultFieldType();
|
||||
ft.setName("field");
|
||||
ft.setIndexOptions(IndexOptions.DOCS);
|
||||
|
||||
assertEquals(new MatchAllDocsQuery(), ft.wildcardQuery("ind*x", null, createContext()));
|
||||
assertEquals(new MatchNoDocsQuery(), ft.wildcardQuery("other_ind*x", null, createContext()));
|
||||
}
|
||||
|
||||
private QueryShardContext createContext() {
|
||||
QueryShardContext context = mock(QueryShardContext.class);
|
||||
|
||||
Index index = new Index("index", "123");
|
||||
when(context.getFullyQualifiedIndex()).thenReturn(index);
|
||||
when(context.index()).thenReturn(index);
|
||||
|
||||
return context;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,12 +18,44 @@
|
|||
*/
|
||||
package org.elasticsearch.index.mapper;
|
||||
|
||||
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||
import org.elasticsearch.index.mapper.RoutingFieldMapper;
|
||||
import org.apache.lucene.index.IndexOptions;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.PrefixQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.RegexpQuery;
|
||||
import org.apache.lucene.search.WildcardQuery;
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
|
||||
public class RoutingFieldTypeTests extends FieldTypeTestCase {
|
||||
@Override
|
||||
protected MappedFieldType createDefaultFieldType() {
|
||||
return new RoutingFieldMapper.RoutingFieldType();
|
||||
}
|
||||
|
||||
public void testPrefixQuery() {
|
||||
MappedFieldType ft = createDefaultFieldType();
|
||||
ft.setName("field");
|
||||
ft.setIndexOptions(IndexOptions.DOCS);
|
||||
|
||||
Query expected = new PrefixQuery(new Term("field", new BytesRef("foo*")));
|
||||
assertEquals(expected, ft.prefixQuery("foo*", null, null));
|
||||
}
|
||||
|
||||
public void testRegexpQuery() {
|
||||
MappedFieldType ft = createDefaultFieldType();
|
||||
ft.setName("field");
|
||||
ft.setIndexOptions(IndexOptions.DOCS);
|
||||
|
||||
Query expected = new RegexpQuery(new Term("field", new BytesRef("foo?")));
|
||||
assertEquals(expected, ft.regexpQuery("foo?", 0, 10, null, null));
|
||||
}
|
||||
|
||||
public void testWildcardQuery() {
|
||||
MappedFieldType ft = createDefaultFieldType();
|
||||
ft.setName("field");
|
||||
ft.setIndexOptions(IndexOptions.DOCS);
|
||||
|
||||
Query expected = new WildcardQuery(new Term("field", new BytesRef("foo*")));
|
||||
assertEquals(expected, ft.wildcardQuery("foo*", null, null));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue