|
@@ -67,7 +67,6 @@ import org.elasticsearch.xcontent.XContentBuilder;
|
|
|
import java.io.IOException;
|
|
|
import java.io.UncheckedIOException;
|
|
|
import java.util.ArrayList;
|
|
|
-import java.util.Arrays;
|
|
|
import java.util.Collections;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
@@ -253,11 +252,18 @@ public class MatchOnlyTextFieldMapper extends FieldMapper {
|
|
|
if (searchExecutionContext.isSourceSynthetic() && withinMultiField) {
|
|
|
String parentField = searchExecutionContext.parentPath(name());
|
|
|
var parent = searchExecutionContext.lookup().fieldType(parentField);
|
|
|
- if (parent.isStored()) {
|
|
|
- if (parent instanceof KeywordFieldMapper.KeywordFieldType keywordParent
|
|
|
- && keywordParent.ignoreAbove() != Integer.MAX_VALUE) {
|
|
|
+
|
|
|
+ if (parent instanceof KeywordFieldMapper.KeywordFieldType keywordParent
|
|
|
+ && keywordParent.ignoreAbove() != Integer.MAX_VALUE) {
|
|
|
+ if (parent.isStored()) {
|
|
|
return storedFieldFetcher(parentField, keywordParent.originalName());
|
|
|
+ } else if (parent.hasDocValues()) {
|
|
|
+ var ifd = searchExecutionContext.getForField(parent, MappedFieldType.FielddataOperation.SEARCH);
|
|
|
+ return combineFieldFetchers(docValuesFieldFetcher(ifd), storedFieldFetcher(keywordParent.originalName()));
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ if (parent.isStored()) {
|
|
|
return storedFieldFetcher(parentField);
|
|
|
} else if (parent.hasDocValues()) {
|
|
|
var ifd = searchExecutionContext.getForField(parent, MappedFieldType.FielddataOperation.SEARCH);
|
|
@@ -268,14 +274,21 @@ public class MatchOnlyTextFieldMapper extends FieldMapper {
|
|
|
} else if (searchExecutionContext.isSourceSynthetic() && hasCompatibleMultiFields) {
|
|
|
var mapper = (MatchOnlyTextFieldMapper) searchExecutionContext.getMappingLookup().getMapper(name());
|
|
|
var kwd = TextFieldMapper.SyntheticSourceHelper.getKeywordFieldMapperForSyntheticSource(mapper);
|
|
|
+
|
|
|
if (kwd != null) {
|
|
|
var fieldType = kwd.fieldType();
|
|
|
- if (fieldType.isStored()) {
|
|
|
- if (fieldType.ignoreAbove() != Integer.MAX_VALUE) {
|
|
|
+
|
|
|
+ if (fieldType.ignoreAbove() != Integer.MAX_VALUE) {
|
|
|
+ if (fieldType.isStored()) {
|
|
|
return storedFieldFetcher(fieldType.name(), fieldType.originalName());
|
|
|
- } else {
|
|
|
- return storedFieldFetcher(fieldType.name());
|
|
|
+ } else if (fieldType.hasDocValues()) {
|
|
|
+ var ifd = searchExecutionContext.getForField(fieldType, MappedFieldType.FielddataOperation.SEARCH);
|
|
|
+ return combineFieldFetchers(docValuesFieldFetcher(ifd), storedFieldFetcher(fieldType.originalName()));
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ if (fieldType.isStored()) {
|
|
|
+ return storedFieldFetcher(fieldType.name());
|
|
|
} else if (fieldType.hasDocValues()) {
|
|
|
var ifd = searchExecutionContext.getForField(fieldType, MappedFieldType.FielddataOperation.SEARCH);
|
|
|
return docValuesFieldFetcher(ifd);
|
|
@@ -332,7 +345,42 @@ public class MatchOnlyTextFieldMapper extends FieldMapper {
|
|
|
if (names.length == 1) {
|
|
|
return storedFields.get(names[0]);
|
|
|
}
|
|
|
- return Arrays.stream(names).map(storedFields::get).filter(Objects::nonNull).flatMap(List::stream).toList();
|
|
|
+
|
|
|
+ List<Object> values = new ArrayList<>();
|
|
|
+ for (var name : names) {
|
|
|
+ var currValues = storedFields.get(name);
|
|
|
+ if (currValues != null) {
|
|
|
+ values.addAll(currValues);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return values;
|
|
|
+ };
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ private static IOFunction<LeafReaderContext, CheckedIntFunction<List<Object>, IOException>> combineFieldFetchers(
|
|
|
+ IOFunction<LeafReaderContext, CheckedIntFunction<List<Object>, IOException>> primaryFetcher,
|
|
|
+ IOFunction<LeafReaderContext, CheckedIntFunction<List<Object>, IOException>> secondaryFetcher
|
|
|
+ ) {
|
|
|
+ return context -> {
|
|
|
+ var primaryGetter = primaryFetcher.apply(context);
|
|
|
+ var secondaryGetter = secondaryFetcher.apply(context);
|
|
|
+ return docId -> {
|
|
|
+ List<Object> values = new ArrayList<>();
|
|
|
+ var primary = primaryGetter.apply(docId);
|
|
|
+ if (primary != null) {
|
|
|
+ values.addAll(primary);
|
|
|
+ }
|
|
|
+
|
|
|
+ var secondary = secondaryGetter.apply(docId);
|
|
|
+ if (secondary != null) {
|
|
|
+ values.addAll(secondary);
|
|
|
+ }
|
|
|
+
|
|
|
+ assert primary != null || secondary != null;
|
|
|
+
|
|
|
+ return values;
|
|
|
};
|
|
|
};
|
|
|
}
|