67
67
import java .io .IOException ;
68
68
import java .io .UncheckedIOException ;
69
69
import java .util .ArrayList ;
70
- import java .util .Arrays ;
71
70
import java .util .Collections ;
72
71
import java .util .List ;
73
72
import java .util .Map ;
@@ -247,11 +246,18 @@ private IOFunction<LeafReaderContext, CheckedIntFunction<List<Object>, IOExcepti
247
246
if (searchExecutionContext .isSourceSynthetic () && withinMultiField ) {
248
247
String parentField = searchExecutionContext .parentPath (name ());
249
248
var parent = searchExecutionContext .lookup ().fieldType (parentField );
250
- if (parent .isStored ()) {
251
- if (parent instanceof KeywordFieldMapper .KeywordFieldType keywordParent
252
- && keywordParent .ignoreAbove () != Integer .MAX_VALUE ) {
249
+
250
+ if (parent instanceof KeywordFieldMapper .KeywordFieldType keywordParent
251
+ && keywordParent .ignoreAbove () != Integer .MAX_VALUE ) {
252
+ if (parent .isStored ()) {
253
253
return storedFieldFetcher (parentField , keywordParent .originalName ());
254
+ } else if (parent .hasDocValues ()) {
255
+ var ifd = searchExecutionContext .getForField (parent , MappedFieldType .FielddataOperation .SEARCH );
256
+ return combineFieldFetchers (docValuesFieldFetcher (ifd ), storedFieldFetcher (keywordParent .originalName ()));
254
257
}
258
+ }
259
+
260
+ if (parent .isStored ()) {
255
261
return storedFieldFetcher (parentField );
256
262
} else if (parent .hasDocValues ()) {
257
263
var ifd = searchExecutionContext .getForField (parent , MappedFieldType .FielddataOperation .SEARCH );
@@ -262,14 +268,21 @@ private IOFunction<LeafReaderContext, CheckedIntFunction<List<Object>, IOExcepti
262
268
} else if (searchExecutionContext .isSourceSynthetic () && hasCompatibleMultiFields ) {
263
269
var mapper = (MatchOnlyTextFieldMapper ) searchExecutionContext .getMappingLookup ().getMapper (name ());
264
270
var kwd = TextFieldMapper .SyntheticSourceHelper .getKeywordFieldMapperForSyntheticSource (mapper );
271
+
265
272
if (kwd != null ) {
266
273
var fieldType = kwd .fieldType ();
267
- if (fieldType .isStored ()) {
268
- if (fieldType .ignoreAbove () != Integer .MAX_VALUE ) {
274
+
275
+ if (fieldType .ignoreAbove () != Integer .MAX_VALUE ) {
276
+ if (fieldType .isStored ()) {
269
277
return storedFieldFetcher (fieldType .name (), fieldType .originalName ());
270
- } else {
271
- return storedFieldFetcher (fieldType .name ());
278
+ } else if (fieldType .hasDocValues ()) {
279
+ var ifd = searchExecutionContext .getForField (fieldType , MappedFieldType .FielddataOperation .SEARCH );
280
+ return combineFieldFetchers (docValuesFieldFetcher (ifd ), storedFieldFetcher (fieldType .originalName ()));
272
281
}
282
+ }
283
+
284
+ if (fieldType .isStored ()) {
285
+ return storedFieldFetcher (fieldType .name ());
273
286
} else if (fieldType .hasDocValues ()) {
274
287
var ifd = searchExecutionContext .getForField (fieldType , MappedFieldType .FielddataOperation .SEARCH );
275
288
return docValuesFieldFetcher (ifd );
@@ -326,7 +339,42 @@ private static IOFunction<LeafReaderContext, CheckedIntFunction<List<Object>, IO
326
339
if (names .length == 1 ) {
327
340
return storedFields .get (names [0 ]);
328
341
}
329
- return Arrays .stream (names ).map (storedFields ::get ).filter (Objects ::nonNull ).flatMap (List ::stream ).toList ();
342
+
343
+ List <Object > values = new ArrayList <>();
344
+ for (var name : names ) {
345
+ var currValues = storedFields .get (name );
346
+ if (currValues != null ) {
347
+ values .addAll (currValues );
348
+ }
349
+ }
350
+
351
+ return values ;
352
+ };
353
+ };
354
+ }
355
+
356
+ private static IOFunction <LeafReaderContext , CheckedIntFunction <List <Object >, IOException >> combineFieldFetchers (
357
+ IOFunction <LeafReaderContext , CheckedIntFunction <List <Object >, IOException >> primaryFetcher ,
358
+ IOFunction <LeafReaderContext , CheckedIntFunction <List <Object >, IOException >> secondaryFetcher
359
+ ) {
360
+ return context -> {
361
+ var primaryGetter = primaryFetcher .apply (context );
362
+ var secondaryGetter = secondaryFetcher .apply (context );
363
+ return docId -> {
364
+ List <Object > values = new ArrayList <>();
365
+ var primary = primaryGetter .apply (docId );
366
+ if (primary != null ) {
367
+ values .addAll (primary );
368
+ }
369
+
370
+ var secondary = secondaryGetter .apply (docId );
371
+ if (secondary != null ) {
372
+ values .addAll (secondary );
373
+ }
374
+
375
+ assert primary != null || secondary != null ;
376
+
377
+ return values ;
330
378
};
331
379
};
332
380
}
0 commit comments