diff --git a/core/src/main/java/org/elasticsearch/index/cache/bitset/BitsetFilterCache.java b/core/src/main/java/org/elasticsearch/index/cache/bitset/BitsetFilterCache.java
index 7d3e75f6f5d12..2de8f01dc7153 100644
--- a/core/src/main/java/org/elasticsearch/index/cache/bitset/BitsetFilterCache.java
+++ b/core/src/main/java/org/elasticsearch/index/cache/bitset/BitsetFilterCache.java
@@ -239,7 +239,7 @@ public IndexWarmer.TerminationHandle warmReader(final IndexShard indexShard, fin
hasNested = true;
for (ObjectMapper objectMapper : docMapper.objectMappers().values()) {
if (objectMapper.nested().isNested()) {
- ObjectMapper parentObjectMapper = docMapper.findParentObjectMapper(objectMapper);
+ ObjectMapper parentObjectMapper = objectMapper.getParentObjectMapper(mapperService);
if (parentObjectMapper != null && parentObjectMapper.nested().isNested()) {
warmUp.add(parentObjectMapper.nestedTypeFilter());
}
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java
index 1dfb7b19eb259..c4de559d1d956 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/DocumentMapper.java
@@ -292,21 +292,6 @@ public ObjectMapper findNestedObjectMapper(int nestedDocId, SearchContext sc, Le
return nestedObjectMapper;
}
- /**
- * Returns the parent {@link ObjectMapper} instance of the specified object mapper or null
if there
- * isn't any.
- */
- // TODO: We should add: ObjectMapper#getParentObjectMapper()
- public ObjectMapper findParentObjectMapper(ObjectMapper objectMapper) {
- int indexOfLastDot = objectMapper.fullPath().lastIndexOf('.');
- if (indexOfLastDot != -1) {
- String parentNestObjectPath = objectMapper.fullPath().substring(0, indexOfLastDot);
- return objectMappers().get(parentNestObjectPath);
- } else {
- return null;
- }
- }
-
public boolean isParent(String type) {
return mapperService.getParentTypes().contains(type);
}
diff --git a/core/src/main/java/org/elasticsearch/index/mapper/ObjectMapper.java b/core/src/main/java/org/elasticsearch/index/mapper/ObjectMapper.java
index fe592835f97a2..d83ce173d6896 100644
--- a/core/src/main/java/org/elasticsearch/index/mapper/ObjectMapper.java
+++ b/core/src/main/java/org/elasticsearch/index/mapper/ObjectMapper.java
@@ -396,6 +396,35 @@ public final Dynamic dynamic() {
return dynamic;
}
+ /**
+ * Returns the parent {@link ObjectMapper} instance of the specified object mapper or null
if there
+ * isn't any.
+ */
+ public ObjectMapper getParentObjectMapper(MapperService mapperService) {
+ int indexOfLastDot = fullPath().lastIndexOf('.');
+ if (indexOfLastDot != -1) {
+ String parentNestObjectPath = fullPath().substring(0, indexOfLastDot);
+ return mapperService.getObjectMapper(parentNestObjectPath);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Returns whether all parent objects fields are nested too.
+ */
+ public boolean parentObjectMapperAreNested(MapperService mapperService) {
+ for (ObjectMapper parent = getParentObjectMapper(mapperService);
+ parent != null;
+ parent = parent.getParentObjectMapper(mapperService)) {
+
+ if (parent.nested().isNested() == false) {
+ return false;
+ }
+ }
+ return true;
+ }
+
@Override
public ObjectMapper merge(Mapper mergeWith, boolean updateAllTypes) {
if (!(mergeWith instanceof ObjectMapper)) {
diff --git a/core/src/main/java/org/elasticsearch/search/fetch/FetchPhase.java b/core/src/main/java/org/elasticsearch/search/fetch/FetchPhase.java
index 8892a69f2dfc1..f05e38636a0cd 100644
--- a/core/src/main/java/org/elasticsearch/search/fetch/FetchPhase.java
+++ b/core/src/main/java/org/elasticsearch/search/fetch/FetchPhase.java
@@ -40,6 +40,7 @@
import org.elasticsearch.index.fieldvisitor.FieldsVisitor;
import org.elasticsearch.index.mapper.DocumentMapper;
import org.elasticsearch.index.mapper.MappedFieldType;
+import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.ObjectMapper;
import org.elasticsearch.index.mapper.SourceFieldMapper;
import org.elasticsearch.index.mapper.Uid;
@@ -246,7 +247,7 @@ private SearchHit createNestedSearchHit(SearchContext context, int nestedTopDocI
ObjectMapper nestedObjectMapper = documentMapper.findNestedObjectMapper(nestedSubDocId, context, subReaderContext);
assert nestedObjectMapper != null;
SearchHit.NestedIdentity nestedIdentity =
- getInternalNestedIdentity(context, nestedSubDocId, subReaderContext, documentMapper, nestedObjectMapper);
+ getInternalNestedIdentity(context, nestedSubDocId, subReaderContext, context.mapperService(), nestedObjectMapper);
if (source != null) {
Tuple> tuple = XContentHelper.convertToMap(source, true);
@@ -262,18 +263,28 @@ private SearchHit createNestedSearchHit(SearchContext context, int nestedTopDocI
String nestedPath = nested.getField().string();
current.put(nestedPath, new HashMap<>());
Object extractedValue = XContentMapValues.extractValue(nestedPath, sourceAsMap);
- List