|
16 | 16 | import org.apache.lucene.util.BytesRef;
|
17 | 17 | import org.elasticsearch.common.Strings;
|
18 | 18 | import org.elasticsearch.common.bytes.BytesReference;
|
| 19 | +import org.elasticsearch.common.io.stream.BytesStreamOutput; |
19 | 20 | import org.elasticsearch.common.util.CollectionUtils;
|
20 |
| -import org.elasticsearch.common.xcontent.XContentFieldFilter; |
| 21 | +import org.elasticsearch.common.xcontent.XContentHelper; |
| 22 | +import org.elasticsearch.common.xcontent.support.XContentMapValues; |
21 | 23 | import org.elasticsearch.core.Nullable;
|
| 24 | +import org.elasticsearch.core.Tuple; |
22 | 25 | import org.elasticsearch.index.query.QueryShardException;
|
23 | 26 | import org.elasticsearch.index.query.SearchExecutionContext;
|
| 27 | +import org.elasticsearch.xcontent.XContentBuilder; |
| 28 | +import org.elasticsearch.xcontent.XContentFactory; |
24 | 29 | import org.elasticsearch.xcontent.XContentType;
|
25 | 30 |
|
26 | 31 | import java.io.IOException;
|
27 | 32 | import java.util.Arrays;
|
28 | 33 | import java.util.Collections;
|
29 | 34 | import java.util.List;
|
| 35 | +import java.util.Map; |
| 36 | +import java.util.function.Function; |
30 | 37 |
|
31 | 38 | public class SourceFieldMapper extends MetadataFieldMapper {
|
| 39 | + |
32 | 40 | public static final String NAME = "_source";
|
33 | 41 | public static final String RECOVERY_SOURCE_NAME = "_recovery_source";
|
34 | 42 |
|
35 | 43 | public static final String CONTENT_TYPE = "_source";
|
36 |
| - private final XContentFieldFilter filter; |
| 44 | + private final Function<Map<String, ?>, Map<String, Object>> filter; |
37 | 45 |
|
38 | 46 | private static final SourceFieldMapper DEFAULT = new SourceFieldMapper(Defaults.ENABLED, Strings.EMPTY_ARRAY, Strings.EMPTY_ARRAY);
|
39 | 47 |
|
@@ -137,9 +145,7 @@ private SourceFieldMapper(boolean enabled, String[] includes, String[] excludes)
|
137 | 145 | this.includes = includes;
|
138 | 146 | this.excludes = excludes;
|
139 | 147 | final boolean filtered = CollectionUtils.isEmpty(includes) == false || CollectionUtils.isEmpty(excludes) == false;
|
140 |
| - this.filter = enabled && filtered |
141 |
| - ? XContentFieldFilter.newFieldFilter(includes, excludes) |
142 |
| - : (sourceBytes, contentType) -> sourceBytes; |
| 148 | + this.filter = enabled && filtered ? XContentMapValues.filter(includes, excludes) : null; |
143 | 149 | this.complete = enabled && CollectionUtils.isEmpty(includes) && CollectionUtils.isEmpty(excludes);
|
144 | 150 | }
|
145 | 151 |
|
@@ -174,7 +180,18 @@ public void preParse(DocumentParserContext context) throws IOException {
|
174 | 180 | public BytesReference applyFilters(@Nullable BytesReference originalSource, @Nullable XContentType contentType) throws IOException {
|
175 | 181 | if (enabled && originalSource != null) {
|
176 | 182 | // Percolate and tv APIs may not set the source and that is ok, because these APIs will not index any data
|
177 |
| - return filter.apply(originalSource, contentType); |
| 183 | + if (filter != null) { |
| 184 | + // we don't update the context source if we filter, we want to keep it as is... |
| 185 | + Tuple<XContentType, Map<String, Object>> mapTuple = XContentHelper.convertToMap(originalSource, true, contentType); |
| 186 | + Map<String, Object> filteredSource = filter.apply(mapTuple.v2()); |
| 187 | + BytesStreamOutput bStream = new BytesStreamOutput(); |
| 188 | + XContentType actualContentType = mapTuple.v1(); |
| 189 | + XContentBuilder builder = XContentFactory.contentBuilder(actualContentType, bStream).map(filteredSource); |
| 190 | + builder.close(); |
| 191 | + return bStream.bytes(); |
| 192 | + } else { |
| 193 | + return originalSource; |
| 194 | + } |
178 | 195 | } else {
|
179 | 196 | return null;
|
180 | 197 | }
|
|
0 commit comments