add explicit termsFilter in mapper, and use that in terms filter

This also enabled support for terms filter on _id field for example
This commit is contained in:
Shay Banon 2012-12-29 01:06:32 -08:00
parent 2655c2aa58
commit b08e8fb76c
5 changed files with 39 additions and 11 deletions

View File

@ -32,6 +32,8 @@ import org.elasticsearch.index.field.data.FieldDataType;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.index.similarity.SimilarityProvider;
import java.util.List;
/**
*
*/
@ -167,6 +169,8 @@ public interface FieldMapper<T> {
Filter termFilter(Object value, @Nullable QueryParseContext context);
Filter termsFilter(List<Object> values, @Nullable QueryParseContext context);
Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context);
Filter rangeFilter(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context);

View File

@ -32,6 +32,7 @@ import org.elasticsearch.common.lucene.BytesRefs;
import org.elasticsearch.common.lucene.Lucene;
import org.elasticsearch.common.lucene.search.RegexpFilter;
import org.elasticsearch.common.lucene.search.TermFilter;
import org.elasticsearch.common.lucene.search.XTermsFilter;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.analysis.NamedAnalyzer;
import org.elasticsearch.index.codec.postingsformat.PostingFormats;
@ -42,6 +43,7 @@ import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.index.similarity.SimilarityProvider;
import java.io.IOException;
import java.util.List;
/**
*
@ -408,6 +410,15 @@ public abstract class AbstractFieldMapper<T> implements FieldMapper<T>, Mapper {
return new TermFilter(names().createIndexNameTerm(indexedValueForSearch(value)));
}
@Override
public Filter termsFilter(List<Object> values, @Nullable QueryParseContext context) {
Term[] terms = new Term[values.size()];
for (int i = 0; i < terms.length; i++) {
terms[i] = names().createIndexNameTerm(indexedValueForSearch(values.get(i)));
}
return new XTermsFilter(terms);
}
@Override
public Query rangeQuery(Object lowerTerm, Object upperTerm, boolean includeLower, boolean includeUpper, @Nullable QueryParseContext context) {
return new TermRangeQuery(names.indexName(),

View File

@ -29,6 +29,7 @@ import org.apache.lucene.search.*;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.lucene.BytesRefs;
import org.elasticsearch.common.lucene.Lucene;
import org.elasticsearch.common.lucene.search.RegexpFilter;
import org.elasticsearch.common.lucene.search.XBooleanFilter;
@ -41,7 +42,9 @@ import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.index.search.UidFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import static org.elasticsearch.index.mapper.MapperBuilders.id;
@ -166,13 +169,19 @@ public class IdFieldMapper extends AbstractFieldMapper<String> implements Intern
if (fieldType.indexed() || context == null) {
return super.termFilter(value, context);
}
BytesRef bytesRef;
if (value instanceof BytesRef) {
bytesRef = (BytesRef) value;
} else {
bytesRef = new BytesRef(value.toString());
return new UidFilter(context.queryTypes(), ImmutableList.of(BytesRefs.toBytesRef(value)));
}
@Override
public Filter termsFilter(List<Object> values, @Nullable QueryParseContext context) {
if (fieldType.indexed() || context == null) {
return super.termsFilter(values, context);
}
return new UidFilter(context.queryTypes(), ImmutableList.of(bytesRef));
List<BytesRef> bytesRefs = new ArrayList<BytesRef>(values.size());
for (Object value : values) {
bytesRefs.add(BytesRefs.toBytesRef(value));
}
return new UidFilter(context.queryTypes(), bytesRefs);
}
@Override

View File

@ -114,17 +114,15 @@ public class TermsFilterParser implements FilterParser {
try {
Filter filter;
if ("plain".equals(execution)) {
Term[] filterTerms = new Term[terms.size()];
if (fieldMapper != null) {
for (int i = 0; i < filterTerms.length; i++) {
filterTerms[i] = fieldMapper.names().createIndexNameTerm(fieldMapper.indexedValueForSearch(terms.get(i)));
}
filter = fieldMapper.termsFilter(terms, parseContext);
} else {
Term[] filterTerms = new Term[terms.size()];
for (int i = 0; i < filterTerms.length; i++) {
filterTerms[i] = new Term(fieldName, BytesRefs.toBytesRef(terms.get(i)));
}
filter = new XTermsFilter(filterTerms);
}
filter = new XTermsFilter(filterTerms);
// cache the whole filter by default, or if explicitly told to
if (cache == null || cache) {
filter = parseContext.cacheFilter(filter, cacheKey);

View File

@ -260,6 +260,12 @@ public class SimpleQueryTests extends AbstractNodesTests {
searchResponse = client.prepareSearch().setQuery(idsQuery("type1").ids("7", "10")).execute().actionGet();
assertThat(searchResponse.hits().totalHits(), equalTo(0l));
// repeat..., with terms
searchResponse = client.prepareSearch().setTypes("type1").setQuery(constantScoreQuery(termsFilter("_id", "1", "3"))).execute().actionGet();
assertThat(searchResponse.hits().totalHits(), equalTo(2l));
assertThat(searchResponse.hits().getAt(0).id(), anyOf(equalTo("1"), equalTo("3")));
assertThat(searchResponse.hits().getAt(1).id(), anyOf(equalTo("1"), equalTo("3")));
}
@Test