@@ -253,11 +253,18 @@ private IOFunction<LeafReaderContext, CheckedIntFunction<List<Object>, IOExcepti
253253 if (searchExecutionContext .isSourceSynthetic () && withinMultiField ) {
254254 String parentField = searchExecutionContext .parentPath (name ());
255255 var parent = searchExecutionContext .lookup ().fieldType (parentField );
256- if (parent .isStored ()) {
257- if (parent instanceof KeywordFieldMapper .KeywordFieldType keywordParent
258- && keywordParent .ignoreAbove () != Integer .MAX_VALUE ) {
256+
257+ if (parent instanceof KeywordFieldMapper .KeywordFieldType keywordParent
258+ && keywordParent .ignoreAbove () != Integer .MAX_VALUE ) {
259+ if (parent .isStored ()) {
259260 return storedFieldFetcher (parentField , keywordParent .originalName ());
261+ } else if (parent .hasDocValues ()) {
262+ var ifd = searchExecutionContext .getForField (parent , MappedFieldType .FielddataOperation .SEARCH );
263+ return combineFieldFetchers (docValuesFieldFetcher (ifd ), storedFieldFetcher (keywordParent .originalName ()));
260264 }
265+ }
266+
267+ if (parent .isStored ()) {
261268 return storedFieldFetcher (parentField );
262269 } else if (parent .hasDocValues ()) {
263270 var ifd = searchExecutionContext .getForField (parent , MappedFieldType .FielddataOperation .SEARCH );
@@ -268,14 +275,21 @@ private IOFunction<LeafReaderContext, CheckedIntFunction<List<Object>, IOExcepti
268275 } else if (searchExecutionContext .isSourceSynthetic () && hasCompatibleMultiFields ) {
269276 var mapper = (MatchOnlyTextFieldMapper ) searchExecutionContext .getMappingLookup ().getMapper (name ());
270277 var kwd = TextFieldMapper .SyntheticSourceHelper .getKeywordFieldMapperForSyntheticSource (mapper );
278+
271279 if (kwd != null ) {
272280 var fieldType = kwd .fieldType ();
273- if (fieldType .isStored ()) {
274- if (fieldType .ignoreAbove () != Integer .MAX_VALUE ) {
281+
282+ if (fieldType .ignoreAbove () != Integer .MAX_VALUE ) {
283+ if (fieldType .isStored ()) {
275284 return storedFieldFetcher (fieldType .name (), fieldType .originalName ());
276- } else {
277- return storedFieldFetcher (fieldType .name ());
285+ } else if (fieldType .hasDocValues ()) {
286+ var ifd = searchExecutionContext .getForField (fieldType , MappedFieldType .FielddataOperation .SEARCH );
287+ return combineFieldFetchers (docValuesFieldFetcher (ifd ), storedFieldFetcher (fieldType .originalName ()));
278288 }
289+ }
290+
291+ if (fieldType .isStored ()) {
292+ return storedFieldFetcher (fieldType .name ());
279293 } else if (fieldType .hasDocValues ()) {
280294 var ifd = searchExecutionContext .getForField (fieldType , MappedFieldType .FielddataOperation .SEARCH );
281295 return docValuesFieldFetcher (ifd );
@@ -337,6 +351,32 @@ private static IOFunction<LeafReaderContext, CheckedIntFunction<List<Object>, IO
337351 };
338352 }
339353
354+ private static IOFunction <LeafReaderContext , CheckedIntFunction <List <Object >, IOException >> combineFieldFetchers (
355+ IOFunction <LeafReaderContext , CheckedIntFunction <List <Object >, IOException >> primaryFetcher ,
356+ IOFunction <LeafReaderContext , CheckedIntFunction <List <Object >, IOException >> secondaryFetcher
357+ ) {
358+ return context -> {
359+ var primaryGetter = primaryFetcher .apply (context );
360+ var secondaryGetter = secondaryFetcher .apply (context );
361+ return docId -> {
362+ List <Object > values = new ArrayList <>();
363+ var primary = primaryGetter .apply (docId );
364+ if (primary != null ) {
365+ values .addAll (primary );
366+ }
367+
368+ var secondary = secondaryGetter .apply (docId );
369+ if (secondary != null ) {
370+ values .addAll (secondary );
371+ }
372+
373+ assert primary != null || secondary != null ;
374+
375+ return values ;
376+ };
377+ };
378+ }
379+
340380 private Query toQuery (Query query , SearchExecutionContext searchExecutionContext ) {
341381 return new ConstantScoreQuery (
342382 new SourceConfirmedTextQuery (query , getValueFetcherProvider (searchExecutionContext ), indexAnalyzer )
0 commit comments