2222import org .apache .lucene .index .LeafReaderContext ;
2323import org .apache .lucene .index .ReaderUtil ;
2424import org .elasticsearch .common .document .DocumentField ;
25- import org .elasticsearch .common .xcontent .support .XContentMapValues ;
2625import org .elasticsearch .index .mapper .DocumentMapper ;
2726import org .elasticsearch .search .SearchHit ;
2827import org .elasticsearch .search .fetch .FetchSubPhase ;
2928import org .elasticsearch .search .internal .SearchContext ;
3029import org .elasticsearch .search .lookup .SourceLookup ;
3130
32- import java .util .Collection ;
33- import java .util .HashMap ;
34- import java .util .HashSet ;
35- import java .util .List ;
3631import java .util .Map ;
37- import java .util .Set ;
38- import java .util .function .Function ;
3932
4033/**
4134 * A fetch sub-phase for high-level field retrieval. Given a list of fields, it
@@ -45,14 +38,6 @@ public final class FetchFieldsPhase implements FetchSubPhase {
4538
4639 @ Override
4740 public void hitsExecute (SearchContext context , SearchHit [] hits ) {
48- hitsExecute (context , hit -> getSourceLookup (context , hit ), hits );
49- }
50-
51- // Visible for testing.
52- @ SuppressWarnings ("unchecked" )
53- void hitsExecute (SearchContext context ,
54- Function <SearchHit , SourceLookup > sourceProvider ,
55- SearchHit [] hits ) {
5641 FetchFieldsContext fetchFieldsContext = context .fetchFieldsContext ();
5742 if (fetchFieldsContext == null || fetchFieldsContext .fields ().isEmpty ()) {
5843 return ;
@@ -64,52 +49,18 @@ void hitsExecute(SearchContext context,
6449 "disabled in the mappings for index [" + context .indexShard ().shardId ().getIndexName () + "]" );
6550 }
6651
67- Set <String > fields = new HashSet <>();
68- for (String fieldPattern : context .fetchFieldsContext ().fields ()) {
69- if (documentMapper .objectMappers ().containsKey (fieldPattern )) {
70- continue ;
71- }
72- Collection <String > concreteFields = context .mapperService ().simpleMatchToFullName (fieldPattern );
73- fields .addAll (concreteFields );
74- }
52+ SourceLookup sourceLookup = context .lookup ().source ();
53+ FieldValueRetriever fieldValueRetriever = FieldValueRetriever .create (
54+ context .mapperService (),
55+ fetchFieldsContext .fields ());
7556
7657 for (SearchHit hit : hits ) {
77- SourceLookup sourceLookup = sourceProvider .apply (hit );
78- Map <String , Object > valuesByField = extractValues (sourceLookup , fields );
79-
80- for (Map .Entry <String , Object > entry : valuesByField .entrySet ()) {
81- String field = entry .getKey ();
82- Object value = entry .getValue ();
83- List <Object > values = value instanceof List
84- ? (List <Object >) value
85- : List .of (value );
86-
87- DocumentField documentField = new DocumentField (field , values );
88- hit .setField (field , documentField );
89- }
90- }
91- }
92-
93- private SourceLookup getSourceLookup (SearchContext context , SearchHit hit ) {
94- SourceLookup sourceLookup = context .lookup ().source ();
95- int readerIndex = ReaderUtil .subIndex (hit .docId (), context .searcher ().getIndexReader ().leaves ());
96- LeafReaderContext readerContext = context .searcher ().getIndexReader ().leaves ().get (readerIndex );
97- sourceLookup .setSegmentAndDocument (readerContext , hit .docId ());
98- return sourceLookup ;
99- }
58+ int readerIndex = ReaderUtil .subIndex (hit .docId (), context .searcher ().getIndexReader ().leaves ());
59+ LeafReaderContext readerContext = context .searcher ().getIndexReader ().leaves ().get (readerIndex );
60+ sourceLookup .setSegmentAndDocument (readerContext , hit .docId ());
10061
101- /**
102- * For each of the provided paths, return its value in the source. Note that in contrast with
103- * {@link SourceLookup#extractRawValues}, array and object values can be returned.
104- */
105- private Map <String , Object > extractValues (SourceLookup sourceLookup , Collection <String > paths ) {
106- Map <String , Object > result = new HashMap <>(paths .size ());
107- for (String path : paths ) {
108- Object value = XContentMapValues .extractValue (path , sourceLookup );
109- if (value != null ) {
110- result .put (path , value );
111- }
62+ Map <String , DocumentField > fieldValues = fieldValueRetriever .retrieve (sourceLookup );
63+ hit .fields (fieldValues );
11264 }
113- return result ;
11465 }
11566}
0 commit comments