|
76 | 76 | import org.elasticsearch.search.aggregations.support.CoreValuesSourceType; |
77 | 77 | import org.elasticsearch.xcontent.ToXContent; |
78 | 78 | import org.elasticsearch.xcontent.XContentBuilder; |
| 79 | +import org.elasticsearch.xcontent.XContentParser; |
79 | 80 |
|
80 | 81 | import java.io.IOException; |
81 | 82 | import java.util.ArrayList; |
@@ -1063,7 +1064,7 @@ public boolean canUseSyntheticSourceDelegateForQueryingEquality(String str) { |
1063 | 1064 | return syntheticSourceDelegate.get().ignoreAbove().isIgnored(str) == false; |
1064 | 1065 | } |
1065 | 1066 |
|
1066 | | - public boolean shouldStoreFieldForSyntheticSource(final IndexVersion indexCreatedVersion) { |
| 1067 | + public boolean storeFieldForSyntheticSource(final IndexVersion indexCreatedVersion) { |
1067 | 1068 | if (multiFieldsNotStoredByDefaultIndexVersionCheck(indexCreatedVersion)) { |
1068 | 1069 | // if we're within a multi field, then supporting synthetic source isn't necessary as that's the responsibility of the |
1069 | 1070 | // parent |
@@ -1106,10 +1107,56 @@ protected String delegatingTo() { |
1106 | 1107 | return new BlockStoredFieldsReader.BytesFromStringsBlockLoader(name()); |
1107 | 1108 | } |
1108 | 1109 |
|
| 1110 | + // if there is no field to delegate to and this field isn't stored, then fallback to ignored source |
| 1111 | + if (isSyntheticSourceEnabled() && syntheticSourceDelegate.isEmpty() && parentField == null) { |
| 1112 | + return fallbackSyntheticSourceBlockLoader(blContext); |
| 1113 | + } |
| 1114 | + |
| 1115 | + // otherwise, load values from _source (synthetic or not) |
1109 | 1116 | SourceValueFetcher fetcher = SourceValueFetcher.toString(blContext.sourcePaths(name())); |
1110 | 1117 | return new BlockSourceReader.BytesRefsBlockLoader(fetcher, blockReaderDisiLookup(blContext)); |
1111 | 1118 | } |
1112 | 1119 |
|
| 1120 | + FallbackSyntheticSourceBlockLoader fallbackSyntheticSourceBlockLoader(BlockLoaderContext blContext) { |
| 1121 | + var reader = new FallbackSyntheticSourceBlockLoader.SingleValueReader<BytesRef>(null) { |
| 1122 | + @Override |
| 1123 | + public void convertValue(Object value, List<BytesRef> accumulator) { |
| 1124 | + if (value != null) { |
| 1125 | + accumulator.add(new BytesRef(value.toString())); |
| 1126 | + } |
| 1127 | + } |
| 1128 | + |
| 1129 | + @Override |
| 1130 | + protected void parseNonNullValue(XContentParser parser, List<BytesRef> accumulator) throws IOException { |
| 1131 | + var text = parser.textOrNull(); |
| 1132 | + |
| 1133 | + if (text != null) { |
| 1134 | + accumulator.add(new BytesRef(text)); |
| 1135 | + } |
| 1136 | + } |
| 1137 | + |
| 1138 | + @Override |
| 1139 | + public void writeToBlock(List<BytesRef> values, BlockLoader.Builder blockBuilder) { |
| 1140 | + var bytesRefBuilder = (BlockLoader.BytesRefBuilder) blockBuilder; |
| 1141 | + |
| 1142 | + for (var value : values) { |
| 1143 | + bytesRefBuilder.appendBytesRef(value); |
| 1144 | + } |
| 1145 | + } |
| 1146 | + }; |
| 1147 | + |
| 1148 | + return new FallbackSyntheticSourceBlockLoader( |
| 1149 | + reader, |
| 1150 | + name(), |
| 1151 | + IgnoredSourceFieldMapper.ignoredSourceFormat(blContext.indexSettings().getIndexVersionCreated()) |
| 1152 | + ) { |
| 1153 | + @Override |
| 1154 | + public Builder builder(BlockFactory factory, int expectedCount) { |
| 1155 | + return factory.bytesRefs(expectedCount); |
| 1156 | + } |
| 1157 | + }; |
| 1158 | + } |
| 1159 | + |
1113 | 1160 | /** |
1114 | 1161 | * Build an iterator of documents that have the field. This mirrors parseCreateField, |
1115 | 1162 | * using whatever |
@@ -1420,7 +1467,7 @@ protected void parseCreateField(DocumentParserContext context) throws IOExceptio |
1420 | 1467 | } |
1421 | 1468 |
|
1422 | 1469 | // store the field if isn't stored yet, and we need it to be stored for synthetic source |
1423 | | - if (fieldType.stored() == false && fieldType().shouldStoreFieldForSyntheticSource(indexCreatedVersion)) { |
| 1470 | + if (fieldType.stored() == false && fieldType().storeFieldForSyntheticSource(indexCreatedVersion)) { |
1424 | 1471 | // if we can rely on the synthetic source delegate for synthetic source, then exit as there is nothing to do |
1425 | 1472 | if (fieldType().canUseSyntheticSourceDelegateForSyntheticSource(value)) { |
1426 | 1473 | return; |
|
0 commit comments