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 ;
@@ -253,11 +252,18 @@ private IOFunction<LeafReaderContext, CheckedIntFunction<List<Object>, IOExcepti
253
252
if (searchExecutionContext .isSourceSynthetic () && withinMultiField ) {
254
253
String parentField = searchExecutionContext .parentPath (name ());
255
254
var parent = searchExecutionContext .lookup ().fieldType (parentField );
256
- if (parent .isStored ()) {
257
- if (parent instanceof KeywordFieldMapper .KeywordFieldType keywordParent
258
- && keywordParent .ignoreAbove () != Integer .MAX_VALUE ) {
255
+
256
+ if (parent instanceof KeywordFieldMapper .KeywordFieldType keywordParent
257
+ && keywordParent .ignoreAbove () != Integer .MAX_VALUE ) {
258
+ if (parent .isStored ()) {
259
259
return storedFieldFetcher (parentField , keywordParent .originalName ());
260
+ } else if (parent .hasDocValues ()) {
261
+ var ifd = searchExecutionContext .getForField (parent , MappedFieldType .FielddataOperation .SEARCH );
262
+ return combineFieldFetchers (docValuesFieldFetcher (ifd ), storedFieldFetcher (keywordParent .originalName ()));
260
263
}
264
+ }
265
+
266
+ if (parent .isStored ()) {
261
267
return storedFieldFetcher (parentField );
262
268
} else if (parent .hasDocValues ()) {
263
269
var ifd = searchExecutionContext .getForField (parent , MappedFieldType .FielddataOperation .SEARCH );
@@ -268,14 +274,21 @@ private IOFunction<LeafReaderContext, CheckedIntFunction<List<Object>, IOExcepti
268
274
} else if (searchExecutionContext .isSourceSynthetic () && hasCompatibleMultiFields ) {
269
275
var mapper = (MatchOnlyTextFieldMapper ) searchExecutionContext .getMappingLookup ().getMapper (name ());
270
276
var kwd = TextFieldMapper .SyntheticSourceHelper .getKeywordFieldMapperForSyntheticSource (mapper );
277
+
271
278
if (kwd != null ) {
272
279
var fieldType = kwd .fieldType ();
273
- if (fieldType .isStored ()) {
274
- if (fieldType .ignoreAbove () != Integer .MAX_VALUE ) {
280
+
281
+ if (fieldType .ignoreAbove () != Integer .MAX_VALUE ) {
282
+ if (fieldType .isStored ()) {
275
283
return storedFieldFetcher (fieldType .name (), fieldType .originalName ());
276
- } else {
277
- return storedFieldFetcher (fieldType .name ());
284
+ } else if (fieldType .hasDocValues ()) {
285
+ var ifd = searchExecutionContext .getForField (fieldType , MappedFieldType .FielddataOperation .SEARCH );
286
+ return combineFieldFetchers (docValuesFieldFetcher (ifd ), storedFieldFetcher (fieldType .originalName ()));
278
287
}
288
+ }
289
+
290
+ if (fieldType .isStored ()) {
291
+ return storedFieldFetcher (fieldType .name ());
279
292
} else if (fieldType .hasDocValues ()) {
280
293
var ifd = searchExecutionContext .getForField (fieldType , MappedFieldType .FielddataOperation .SEARCH );
281
294
return docValuesFieldFetcher (ifd );
@@ -332,7 +345,42 @@ private static IOFunction<LeafReaderContext, CheckedIntFunction<List<Object>, IO
332
345
if (names .length == 1 ) {
333
346
return storedFields .get (names [0 ]);
334
347
}
335
- return Arrays .stream (names ).map (storedFields ::get ).filter (Objects ::nonNull ).flatMap (List ::stream ).toList ();
348
+
349
+ List <Object > values = new ArrayList <>();
350
+ for (var name : names ) {
351
+ var currValues = storedFields .get (name );
352
+ if (currValues != null ) {
353
+ values .addAll (currValues );
354
+ }
355
+ }
356
+
357
+ return values ;
358
+ };
359
+ };
360
+ }
361
+
362
+ private static IOFunction <LeafReaderContext , CheckedIntFunction <List <Object >, IOException >> combineFieldFetchers (
363
+ IOFunction <LeafReaderContext , CheckedIntFunction <List <Object >, IOException >> primaryFetcher ,
364
+ IOFunction <LeafReaderContext , CheckedIntFunction <List <Object >, IOException >> secondaryFetcher
365
+ ) {
366
+ return context -> {
367
+ var primaryGetter = primaryFetcher .apply (context );
368
+ var secondaryGetter = secondaryFetcher .apply (context );
369
+ return docId -> {
370
+ List <Object > values = new ArrayList <>();
371
+ var primary = primaryGetter .apply (docId );
372
+ if (primary != null ) {
373
+ values .addAll (primary );
374
+ }
375
+
376
+ var secondary = secondaryGetter .apply (docId );
377
+ if (secondary != null ) {
378
+ values .addAll (secondary );
379
+ }
380
+
381
+ assert primary != null || secondary != null ;
382
+
383
+ return values ;
336
384
};
337
385
};
338
386
}
0 commit comments