PageRenderTime 53ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/modules/elasticsearch/src/main/java/org/elasticsearch/search/lookup/SourceLookup.java

https://github.com/iw/elasticsearch
Java | 181 lines | 128 code | 27 blank | 26 comment | 12 complexity | 9bd8db5859bbe43c89b7ebc5ab88c535 MD5 | raw file
  1. /*
  2. * Licensed to Elastic Search and Shay Banon under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. Elastic Search licenses this
  6. * file to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing,
  13. * software distributed under the License is distributed on an
  14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. * KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations
  17. * under the License.
  18. */
  19. package org.elasticsearch.search.lookup;
  20. import org.apache.lucene.document.Document;
  21. import org.apache.lucene.document.Fieldable;
  22. import org.apache.lucene.index.IndexReader;
  23. import org.elasticsearch.ElasticSearchParseException;
  24. import org.elasticsearch.common.compress.lzf.LZF;
  25. import org.elasticsearch.common.io.stream.BytesStreamInput;
  26. import org.elasticsearch.common.io.stream.CachedStreamInput;
  27. import org.elasticsearch.common.io.stream.LZFStreamInput;
  28. import org.elasticsearch.common.xcontent.XContentFactory;
  29. import org.elasticsearch.common.xcontent.XContentParser;
  30. import org.elasticsearch.common.xcontent.XContentType;
  31. import org.elasticsearch.common.xcontent.support.XContentMapValues;
  32. import org.elasticsearch.index.mapper.internal.SourceFieldMapper;
  33. import org.elasticsearch.index.mapper.internal.SourceFieldSelector;
  34. import java.util.Collection;
  35. import java.util.List;
  36. import java.util.Map;
  37. import java.util.Set;
  38. /**
  39. * @author kimchy (shay.banon)
  40. */
  41. // TODO: If we are processing it in the per hit fetch phase, we cna initialize it with a source if it was loaded..
  42. public class SourceLookup implements Map {
  43. private IndexReader reader;
  44. private int docId = -1;
  45. private Map<String, Object> source;
  46. public Map<String, Object> source() {
  47. return source;
  48. }
  49. private Map<String, Object> loadSourceIfNeeded() {
  50. if (source != null) {
  51. return source;
  52. }
  53. XContentParser parser = null;
  54. try {
  55. Document doc = reader.document(docId, SourceFieldSelector.INSTANCE);
  56. Fieldable sourceField = doc.getFieldable(SourceFieldMapper.NAME);
  57. byte[] source = sourceField.getBinaryValue();
  58. this.source = sourceAsMap(source, 0, source.length);
  59. } catch (Exception e) {
  60. throw new ElasticSearchParseException("failed to parse / load source", e);
  61. } finally {
  62. if (parser != null) {
  63. parser.close();
  64. }
  65. }
  66. return this.source;
  67. }
  68. public static Map<String, Object> sourceAsMap(byte[] bytes, int offset, int length) {
  69. XContentParser parser = null;
  70. try {
  71. if (LZF.isCompressed(bytes, offset, length)) {
  72. BytesStreamInput siBytes = new BytesStreamInput(bytes, offset, length);
  73. LZFStreamInput siLzf = CachedStreamInput.cachedLzf(siBytes);
  74. XContentType contentType = XContentFactory.xContentType(siLzf);
  75. siLzf.resetToBufferStart();
  76. parser = XContentFactory.xContent(contentType).createParser(siLzf);
  77. return parser.map();
  78. } else {
  79. parser = XContentFactory.xContent(bytes, offset, length).createParser(bytes, offset, length);
  80. return parser.map();
  81. }
  82. } catch (Exception e) {
  83. throw new ElasticSearchParseException("Failed to parse source to map", e);
  84. } finally {
  85. if (parser != null) {
  86. parser.close();
  87. }
  88. }
  89. }
  90. public void setNextReader(IndexReader reader) {
  91. if (this.reader == reader) { // if we are called with the same reader, don't invalidate source
  92. return;
  93. }
  94. this.reader = reader;
  95. this.source = null;
  96. this.docId = -1;
  97. }
  98. public void setNextDocId(int docId) {
  99. if (this.docId == docId) { // if we are called with the same docId, don't invalidate source
  100. return;
  101. }
  102. this.docId = docId;
  103. this.source = null;
  104. }
  105. public void setNextSource(Map<String, Object> source) {
  106. this.source = source;
  107. }
  108. /**
  109. * Returns the values associated with the path. Those are "low" level values, and it can
  110. * handle path expression where an array/list is navigated within.
  111. */
  112. public List<Object> extractRawValues(String path) {
  113. return XContentMapValues.extractRawValues(path, loadSourceIfNeeded());
  114. }
  115. public Object extractValue(String path) {
  116. return XContentMapValues.extractValue(path, loadSourceIfNeeded());
  117. }
  118. @Override public Object get(Object key) {
  119. return loadSourceIfNeeded().get(key);
  120. }
  121. @Override public int size() {
  122. return loadSourceIfNeeded().size();
  123. }
  124. @Override public boolean isEmpty() {
  125. return loadSourceIfNeeded().isEmpty();
  126. }
  127. @Override public boolean containsKey(Object key) {
  128. return loadSourceIfNeeded().containsKey(key);
  129. }
  130. @Override public boolean containsValue(Object value) {
  131. return loadSourceIfNeeded().containsValue(value);
  132. }
  133. @Override public Set keySet() {
  134. return loadSourceIfNeeded().keySet();
  135. }
  136. @Override public Collection values() {
  137. return loadSourceIfNeeded().values();
  138. }
  139. @Override public Set entrySet() {
  140. return loadSourceIfNeeded().entrySet();
  141. }
  142. @Override public Object put(Object key, Object value) {
  143. throw new UnsupportedOperationException();
  144. }
  145. @Override public Object remove(Object key) {
  146. throw new UnsupportedOperationException();
  147. }
  148. @Override public void putAll(Map m) {
  149. throw new UnsupportedOperationException();
  150. }
  151. @Override public void clear() {
  152. throw new UnsupportedOperationException();
  153. }
  154. }