Support using _id:1234, or using term query/filter on _id even when _id is not indexed, closes #1496.

This commit is contained in:
Shay Banon 2011-11-24 12:31:50 +02:00
parent daa4444e22
commit 81965d0ea9
8 changed files with 57 additions and 14 deletions

View File

@ -282,7 +282,7 @@ public class DocumentMapper implements ToXContent {
this.indexAnalyzer = indexAnalyzer;
this.searchAnalyzer = searchAnalyzer;
this.typeFilter = typeMapper().fieldFilter(type);
this.typeFilter = typeMapper().fieldFilter(type, null);
if (rootMapper(ParentFieldMapper.class) != null) {
// mark the routing field mapper as required

View File

@ -25,6 +25,7 @@ import org.apache.lucene.document.Fieldable;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.Query;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.util.concurrent.Immutable;
import org.elasticsearch.common.util.concurrent.ThreadSafe;
import org.elasticsearch.index.field.data.FieldDataType;
@ -156,7 +157,7 @@ public interface FieldMapper<T> {
/**
* A field query for the specified value.
*/
Query fieldQuery(String value, QueryParseContext context);
Query fieldQuery(String value, @Nullable QueryParseContext context);
Query fuzzyQuery(String value, String minSim, int prefixLength, int maxExpansions);
@ -167,7 +168,7 @@ public interface FieldMapper<T> {
*/
Query queryStringTermQuery(Term term);
Filter fieldFilter(String value);
Filter fieldFilter(String value, @Nullable QueryParseContext context);
/**
* Constructs a range query based on the mapper.

View File

@ -30,6 +30,7 @@ import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TermRangeFilter;
import org.apache.lucene.search.TermRangeQuery;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.lucene.Lucene;
import org.elasticsearch.common.lucene.search.TermFilter;
import org.elasticsearch.common.xcontent.XContentBuilder;
@ -342,10 +343,14 @@ public abstract class AbstractFieldMapper<T> implements FieldMapper<T>, Mapper {
return false;
}
@Override public Query fieldQuery(String value, QueryParseContext context) {
@Override public Query fieldQuery(String value, @Nullable QueryParseContext context) {
return new TermQuery(names().createIndexNameTerm(indexedValue(value)));
}
@Override public Filter fieldFilter(String value, @Nullable QueryParseContext context) {
return new TermFilter(names().createIndexNameTerm(indexedValue(value)));
}
@Override public Query fuzzyQuery(String value, String minSim, int prefixLength, int maxExpansions) {
return new FuzzyQuery(names().createIndexNameTerm(indexedValue(value)), Float.parseFloat(minSim), prefixLength, maxExpansions);
}
@ -354,10 +359,6 @@ public abstract class AbstractFieldMapper<T> implements FieldMapper<T>, Mapper {
return new FuzzyQuery(names().createIndexNameTerm(value), (float) minSim, prefixLength, maxExpansions);
}
@Override public Filter fieldFilter(String value) {
return new TermFilter(names().createIndexNameTerm(indexedValue(value)));
}
@Override public Query rangeQuery(String lowerTerm, String upperTerm, boolean includeLower, boolean includeUpper) {
return new TermRangeQuery(names.indexName(),
lowerTerm == null ? null : indexedValue(lowerTerm),

View File

@ -156,7 +156,7 @@ public abstract class NumberFieldMapper<T extends Number> extends AbstractFieldM
* Numeric field level query are basically range queries with same value and included. That's the recommended
* way to execute it.
*/
@Override public Query fieldQuery(String value, QueryParseContext context) {
@Override public Query fieldQuery(String value, @Nullable QueryParseContext context) {
return rangeQuery(value, value, true, true);
}
@ -168,7 +168,7 @@ public abstract class NumberFieldMapper<T extends Number> extends AbstractFieldM
* Numeric field level filter are basically range queries with same value and included. That's the recommended
* way to execute it.
*/
@Override public Filter fieldFilter(String value) {
@Override public Filter fieldFilter(String value, @Nullable QueryParseContext context) {
return rangeFilter(value, value, true, true);
}

View File

@ -22,7 +22,12 @@ package org.elasticsearch.index.mapper.internal;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Fieldable;
import org.apache.lucene.search.ConstantScoreQuery;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.Query;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.ImmutableList;
import org.elasticsearch.common.lucene.Lucene;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
@ -34,6 +39,8 @@ import org.elasticsearch.index.mapper.MergeMappingException;
import org.elasticsearch.index.mapper.ParseContext;
import org.elasticsearch.index.mapper.RootMapper;
import org.elasticsearch.index.mapper.core.AbstractFieldMapper;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.index.search.UidFilter;
import java.io.IOException;
import java.util.Map;
@ -145,6 +152,26 @@ public class IdFieldMapper extends AbstractFieldMapper<String> implements Intern
return value;
}
@Override public boolean useFieldQueryWithQueryString() {
return true;
}
@Override public Query fieldQuery(String value, @Nullable QueryParseContext context) {
if (indexed() || context == null) {
return super.fieldQuery(value, context);
}
UidFilter filter = new UidFilter(context.mapperService().types(), ImmutableList.of(value), context.indexCache().bloomCache());
// no need for constant score filter, since we don't cache the filter, and it always takes deletes into account
return new ConstantScoreQuery(filter);
}
@Override public Filter fieldFilter(String value, @Nullable QueryParseContext context) {
if (indexed() || context == null) {
return super.fieldFilter(value, context);
}
return new UidFilter(context.mapperService().types(), ImmutableList.of(value), context.indexCache().bloomCache());
}
@Override public void preParse(ParseContext context) throws IOException {
if (context.sourceToParse().id() != null) {
context.id(context.sourceToParse().id());

View File

@ -27,6 +27,7 @@ import org.apache.lucene.search.DeletionAwareConstantScoreQuery;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.PrefixFilter;
import org.apache.lucene.search.Query;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.lucene.Lucene;
import org.elasticsearch.common.lucene.search.TermFilter;
import org.elasticsearch.common.xcontent.XContentBuilder;
@ -132,15 +133,15 @@ public class TypeFieldMapper extends AbstractFieldMapper<String> implements Inte
return names().createIndexNameTerm(value);
}
@Override public Filter fieldFilter(String value) {
@Override public Filter fieldFilter(String value, @Nullable QueryParseContext context) {
if (index == Field.Index.NO) {
return new PrefixFilter(UidFieldMapper.TERM_FACTORY.createTerm(Uid.typePrefix(value)));
}
return new TermFilter(names().createIndexNameTerm(value));
}
@Override public Query fieldQuery(String value, QueryParseContext context) {
return new DeletionAwareConstantScoreQuery(context.cacheFilter(fieldFilter(value), null));
@Override public Query fieldQuery(String value, @Nullable QueryParseContext context) {
return new DeletionAwareConstantScoreQuery(context.cacheFilter(fieldFilter(value, context), null));
}
@Override public boolean useFieldQueryWithQueryString() {

View File

@ -85,7 +85,7 @@ public class TermFilterParser implements FilterParser {
MapperService.SmartNameFieldMappers smartNameFieldMappers = parseContext.smartFieldMappers(fieldName);
if (smartNameFieldMappers != null) {
if (smartNameFieldMappers.hasMapper()) {
filter = smartNameFieldMappers.mapper().fieldFilter(value);
filter = smartNameFieldMappers.mapper().fieldFilter(value, parseContext);
}
}
if (filter == null) {

View File

@ -72,6 +72,19 @@ public class SimpleSearchTests extends AbstractNodesTests {
assertThat(search.hits().totalHits(), equalTo(1l));
}
@Test public void simpleIdTests() {
client.admin().indices().prepareDelete().execute().actionGet();
client.admin().indices().prepareCreate("test").setSettings(ImmutableSettings.settingsBuilder().put("number_of_shards", 1)).execute().actionGet();
client.prepareIndex("test", "type", "1").setSource("field", "value").setRefresh(true).execute().actionGet();
// id is not indexed, but lets see that we automatically convert to
SearchResponse searchResponse = client.prepareSearch().setQuery(QueryBuilders.termQuery("_id", "1")).execute().actionGet();
assertThat(searchResponse.hits().totalHits(), equalTo(1l));
searchResponse = client.prepareSearch().setQuery(QueryBuilders.queryString("_id:1")).execute().actionGet();
assertThat(searchResponse.hits().totalHits(), equalTo(1l));
}
@Test public void simpleDateRangeWithUpperInclusiveEnabledTests() throws Exception {
client.admin().indices().prepareDelete().execute().actionGet();
client.admin().indices().prepareCreate("test").setSettings(ImmutableSettings.settingsBuilder()).execute().actionGet();