Support using _id:1234, or using term query/filter on _id even when _id is not indexed, closes #1496.
This commit is contained in:
parent
daa4444e22
commit
81965d0ea9
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue