Nested: If the `_type` field isn't indexed nested docs must be filtered out.

This commit is contained in:
Martijn van Groningen 2014-08-22 19:30:15 +02:00
parent d471abe4d3
commit bd0b68080b
6 changed files with 29 additions and 24 deletions

View File

@ -520,10 +520,12 @@ public class MapperService extends AbstractIndexComponent {
// since they have different types (starting with __) // since they have different types (starting with __)
if (types.length == 1) { if (types.length == 1) {
DocumentMapper docMapper = documentMapper(types[0]); DocumentMapper docMapper = documentMapper(types[0]);
if (docMapper == null) { Filter filter = docMapper != null ? docMapper.typeFilter() : new TermFilter(new Term(types[0]));
return new TermFilter(new Term(types[0])); if (hasNested) {
return new AndFilter(ImmutableList.of(filter, NonNestedDocsFilter.INSTANCE));
} else {
return filter;
} }
return docMapper.typeFilter();
} }
// see if we can use terms filter // see if we can use terms filter
boolean useTermsFilter = true; boolean useTermsFilter = true;
@ -539,6 +541,7 @@ public class MapperService extends AbstractIndexComponent {
} }
} }
// We only use terms filter is there is a type filter, this means we don't need to check for hasNested here
if (useTermsFilter) { if (useTermsFilter) {
BytesRef[] typesBytes = new BytesRef[types.length]; BytesRef[] typesBytes = new BytesRef[types.length];
for (int i = 0; i < typesBytes.length; i++) { for (int i = 0; i < typesBytes.length; i++) {
@ -564,6 +567,9 @@ public class MapperService extends AbstractIndexComponent {
if (filterPercolateType) { if (filterPercolateType) {
bool.add(excludePercolatorType, BooleanClause.Occur.MUST); bool.add(excludePercolatorType, BooleanClause.Occur.MUST);
} }
if (hasNested) {
bool.add(NonNestedDocsFilter.INSTANCE, BooleanClause.Occur.MUST);
}
return bool; return bool;
} }

View File

@ -344,6 +344,9 @@ public class SimpleIndexTemplateTests extends ElasticsearchIntegrationTest {
.filter(FilterBuilders.termsFilter("_type", "typeX", "typeY", "typeZ").execution("bool").cache(true))) .filter(FilterBuilders.termsFilter("_type", "typeX", "typeY", "typeZ").execution("bool").cache(true)))
.get(); .get();
assertAcked(prepareCreate("test_index").addMapping("type1").addMapping("type2").addMapping("typeX").addMapping("typeY").addMapping("typeZ"));
ensureGreen();
client().prepareIndex("test_index", "type1", "1").setSource("field", "A value").get(); client().prepareIndex("test_index", "type1", "1").setSource("field", "A value").get();
client().prepareIndex("test_index", "type2", "2").setSource("field", "B value").get(); client().prepareIndex("test_index", "type2", "2").setSource("field", "B value").get();
client().prepareIndex("test_index", "typeX", "3").setSource("field", "C value").get(); client().prepareIndex("test_index", "typeX", "3").setSource("field", "C value").get();
@ -398,7 +401,7 @@ public class SimpleIndexTemplateTests extends ElasticsearchIntegrationTest {
"}").get(); "}").get();
createIndex("test_index"); assertAcked(prepareCreate("test_index").addMapping("type1").addMapping("type2"));
ensureGreen(); ensureGreen();
GetAliasesResponse getAliasesResponse = client().admin().indices().prepareGetAliases().setIndices("test_index").get(); GetAliasesResponse getAliasesResponse = client().admin().indices().prepareGetAliases().setIndices("test_index").get();
@ -434,7 +437,7 @@ public class SimpleIndexTemplateTests extends ElasticsearchIntegrationTest {
" \"alias3\" : { \"routing\" : \"1\" }" + " \"alias3\" : { \"routing\" : \"1\" }" +
" }\n").get(); " }\n").get();
createIndex("test_index"); assertAcked(prepareCreate("test_index").addMapping("type1").addMapping("type2"));
ensureGreen(); ensureGreen();
GetAliasesResponse getAliasesResponse = client().admin().indices().prepareGetAliases().setIndices("test_index").get(); GetAliasesResponse getAliasesResponse = client().admin().indices().prepareGetAliases().setIndices("test_index").get();

View File

@ -53,21 +53,7 @@ public class SimpleNestedTests extends ElasticsearchIntegrationTest {
@Test @Test
public void simpleNested() throws Exception { public void simpleNested() throws Exception {
XContentBuilder builder = jsonBuilder(). assertAcked(prepareCreate("test").addMapping("type1", "nested1", "type=nested").addMapping("type2", "nested1", "type=nested"));
startObject().
field("type1").
startObject().
field("properties").
startObject().
field("nested1").
startObject().
field("type").
value("nested").
endObject().
endObject().
endObject().
endObject();
assertAcked(prepareCreate("test").addMapping("type1", builder));
ensureGreen(); ensureGreen();
// check on no data, see it works // check on no data, see it works
@ -169,6 +155,10 @@ public class SimpleNestedTests extends ElasticsearchIntegrationTest {
searchResponse = client().prepareSearch("test").setQuery(nestedQuery("nested1", termQuery("nested1.n_field1", "n_value1_1"))).execute().actionGet(); searchResponse = client().prepareSearch("test").setQuery(nestedQuery("nested1", termQuery("nested1.n_field1", "n_value1_1"))).execute().actionGet();
assertNoFailures(searchResponse); assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().totalHits(), equalTo(1l)); assertThat(searchResponse.getHits().totalHits(), equalTo(1l));
searchResponse = client().prepareSearch("test").setTypes("type1", "type2").setQuery(nestedQuery("nested1", termQuery("nested1.n_field1", "n_value1_1"))).execute().actionGet();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().totalHits(), equalTo(1l));
} }
@Test @Test

View File

@ -69,7 +69,7 @@ public class NestedTests extends ElasticsearchIntegrationTest {
numParents = randomIntBetween(3, 10); numParents = randomIntBetween(3, 10);
numChildren = new int[numParents]; numChildren = new int[numParents];
aggCollectionMode = randomFrom(SubAggCollectionMode.values()); aggCollectionMode = randomFrom(SubAggCollectionMode.values());
System.out.println("AGG COLLECTION MODE: " + aggCollectionMode); logger.info("AGG COLLECTION MODE: " + aggCollectionMode);
int totalChildren = 0; int totalChildren = 0;
for (int i = 0; i < numParents; ++i) { for (int i = 0; i < numParents; ++i) {
if (i == numParents - 1 && totalChildren == 0) { if (i == numParents - 1 && totalChildren == 0) {

View File

@ -27,9 +27,8 @@ import org.elasticsearch.action.suggest.SuggestResponse;
import org.elasticsearch.common.geo.GeoHashUtils; import org.elasticsearch.common.geo.GeoHashUtils;
import org.elasticsearch.common.geo.GeoPoint; import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.unit.Fuzziness; import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.common.xcontent.*; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.mapper.MapperParsingException; import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.search.aggregations.support.format.ValueFormatter;
import org.elasticsearch.search.suggest.Suggest.Suggestion; import org.elasticsearch.search.suggest.Suggest.Suggestion;
import org.elasticsearch.search.suggest.Suggest.Suggestion.Entry; import org.elasticsearch.search.suggest.Suggest.Suggestion.Entry;
import org.elasticsearch.search.suggest.Suggest.Suggestion.Entry.Option; import org.elasticsearch.search.suggest.Suggest.Suggestion.Entry.Option;
@ -926,6 +925,7 @@ public class ContextSuggestSearchTests extends ElasticsearchIntegrationTest {
XContentBuilder mapping = jsonBuilder(); XContentBuilder mapping = jsonBuilder();
mapping.startObject(); mapping.startObject();
mapping.startObject(type); mapping.startObject(type);
mapping.startObject("_type").field("index", "not_analyzed").endObject(); // Forcefully configure the _type field, since it can be randomized and if used as context it needs to be enabled
mapping.startObject("properties"); mapping.startObject("properties");
mapping.startObject(FIELD); mapping.startObject(FIELD);
mapping.field("type", "completion"); mapping.field("type", "completion");

View File

@ -76,10 +76,11 @@ import org.elasticsearch.discovery.zen.elect.ElectMasterService;
import org.elasticsearch.index.codec.CodecService; import org.elasticsearch.index.codec.CodecService;
import org.elasticsearch.index.fielddata.FieldDataType; import org.elasticsearch.index.fielddata.FieldDataType;
import org.elasticsearch.index.mapper.DocumentMapper; import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.FieldMapper.Loading;
import org.elasticsearch.index.mapper.FieldMapper; import org.elasticsearch.index.mapper.FieldMapper;
import org.elasticsearch.index.mapper.FieldMapper.Loading;
import org.elasticsearch.index.mapper.internal.FieldNamesFieldMapper; import org.elasticsearch.index.mapper.internal.FieldNamesFieldMapper;
import org.elasticsearch.index.mapper.internal.IdFieldMapper; import org.elasticsearch.index.mapper.internal.IdFieldMapper;
import org.elasticsearch.index.mapper.internal.TypeFieldMapper;
import org.elasticsearch.index.merge.policy.*; import org.elasticsearch.index.merge.policy.*;
import org.elasticsearch.index.merge.scheduler.ConcurrentMergeSchedulerProvider; import org.elasticsearch.index.merge.scheduler.ConcurrentMergeSchedulerProvider;
import org.elasticsearch.index.merge.scheduler.MergeSchedulerModule; import org.elasticsearch.index.merge.scheduler.MergeSchedulerModule;
@ -338,6 +339,11 @@ public abstract class ElasticsearchIntegrationTest extends ElasticsearchTestCase
.field("index", randomFrom("not_analyzed", "no")) .field("index", randomFrom("not_analyzed", "no"))
.endObject(); .endObject();
} }
if (randomBoolean()) {
mappings.startObject(TypeFieldMapper.NAME)
.field("index", randomFrom("no", "not_analyzed"))
.endObject();
}
if (compatibilityVersion().onOrAfter(Version.V_1_3_0)) { if (compatibilityVersion().onOrAfter(Version.V_1_3_0)) {
mappings.startObject(FieldNamesFieldMapper.NAME) mappings.startObject(FieldNamesFieldMapper.NAME)
.startObject("fielddata") .startObject("fielddata")