diff --git a/src/main/java/org/elasticsearch/index/get/ShardGetService.java b/src/main/java/org/elasticsearch/index/get/ShardGetService.java index 8af217bf3ba..43dfc6a2c57 100644 --- a/src/main/java/org/elasticsearch/index/get/ShardGetService.java +++ b/src/main/java/org/elasticsearch/index/get/ShardGetService.java @@ -293,7 +293,7 @@ public class ShardGetService extends AbstractIndexShardComponent { } else { if (searchLookup == null) { searchLookup = new SearchLookup(mapperService, indexCache.fieldData()); - searchLookup.source().setNextSource(SourceLookup.sourceAsMap(source.source.bytes(), source.source.offset(), source.source.length())); + searchLookup.source().setNextSource(source.source.bytes(), source.source.offset(), source.source.length()); } FieldMapper x = docMapper.mappers().smartNameFieldMapper(field); diff --git a/src/main/java/org/elasticsearch/search/fetch/FetchPhase.java b/src/main/java/org/elasticsearch/search/fetch/FetchPhase.java index ca0c1af3e08..79169cd6c26 100644 --- a/src/main/java/org/elasticsearch/search/fetch/FetchPhase.java +++ b/src/main/java/org/elasticsearch/search/fetch/FetchPhase.java @@ -184,6 +184,9 @@ public class FetchPhase implements SearchPhase { // go over and extract fields that are not mapped / stored context.lookup().setNextReader(subReader); context.lookup().setNextDocId(subDoc); + if (source != null) { + context.lookup().source().setNextSource(source, 0, source.length); + } if (extractFieldNames != null) { for (String extractFieldName : extractFieldNames) { Object value = context.lookup().source().extractValue(extractFieldName); diff --git a/src/main/java/org/elasticsearch/search/lookup/SourceLookup.java b/src/main/java/org/elasticsearch/search/lookup/SourceLookup.java index 7047c06f432..655c5c74b45 100644 --- a/src/main/java/org/elasticsearch/search/lookup/SourceLookup.java +++ b/src/main/java/org/elasticsearch/search/lookup/SourceLookup.java @@ -25,7 +25,6 @@ import org.apache.lucene.document.Fieldable; import org.apache.lucene.index.IndexReader; import org.elasticsearch.ElasticSearchParseException; import org.elasticsearch.common.xcontent.XContentHelper; -import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.support.XContentMapValues; import org.elasticsearch.index.mapper.internal.SourceFieldMapper; import org.elasticsearch.index.mapper.internal.SourceFieldSelector; @@ -45,6 +44,9 @@ public class SourceLookup implements Map { private int docId = -1; + private byte[] sourceAsBytes; + private int sourceAsBytesOffset; + private int sourceAsBytesLength; private Map source; public Map source() { @@ -55,7 +57,10 @@ public class SourceLookup implements Map { if (source != null) { return source; } - XContentParser parser = null; + if (sourceAsBytes != null) { + source = sourceAsMap(sourceAsBytes, sourceAsBytesOffset, sourceAsBytesLength); + return source; + } try { Document doc = reader.document(docId, SourceFieldSelector.INSTANCE); Fieldable sourceField = doc.getFieldable(SourceFieldMapper.NAME); @@ -66,10 +71,6 @@ public class SourceLookup implements Map { } } catch (Exception e) { throw new ElasticSearchParseException("failed to parse / load source", e); - } finally { - if (parser != null) { - parser.close(); - } } return this.source; } @@ -84,6 +85,7 @@ public class SourceLookup implements Map { } this.reader = reader; this.source = null; + this.sourceAsBytes = null; this.docId = -1; } @@ -92,9 +94,16 @@ public class SourceLookup implements Map { return; } this.docId = docId; + this.sourceAsBytes = null; this.source = null; } + public void setNextSource(byte[] source, int offset, int length) { + this.sourceAsBytes = source; + this.sourceAsBytesOffset = offset; + this.sourceAsBytesLength = length; + } + public void setNextSource(Map source) { this.source = source; }