3434import java .util .ArrayList ;
3535import java .util .Collection ;
3636import java .util .HashMap ;
37- import java .util .HashSet ;
37+ import java .util .LinkedHashMap ;
3838import java .util .List ;
3939import java .util .Map ;
4040import java .util .Set ;
@@ -48,9 +48,10 @@ public static FieldFetcher create(QueryShardContext context,
4848 SearchLookup searchLookup ,
4949 Collection <FieldAndFormat > fieldAndFormats ) {
5050
51- List <FieldContext > fieldContexts = new ArrayList <>();
51+ // Using a LinkedHashMap so fields are returned in the order requested.
52+ // We won't formally guarantee this but but its good for readability of the response
53+ Map <String , FieldContext > fieldContexts = new LinkedHashMap <>();
5254 List <String > unmappedFetchPattern = new ArrayList <>();
53- Set <String > mappedToExclude = new HashSet <>();
5455 boolean includeUnmapped = false ;
5556
5657 for (FieldAndFormat fieldAndFormat : fieldAndFormats ) {
@@ -68,8 +69,7 @@ public static FieldFetcher create(QueryShardContext context,
6869 continue ;
6970 }
7071 ValueFetcher valueFetcher = ft .valueFetcher (context , format );
71- mappedToExclude .add (field );
72- fieldContexts .add (new FieldContext (field , valueFetcher ));
72+ fieldContexts .put (field , new FieldContext (field , valueFetcher ));
7373 }
7474 }
7575 CharacterRunAutomaton unmappedFetchAutomaton = new CharacterRunAutomaton (Automata .makeEmpty ());
@@ -78,29 +78,26 @@ public static FieldFetcher create(QueryShardContext context,
7878 Regex .simpleMatchToAutomaton (unmappedFetchPattern .toArray (new String [unmappedFetchPattern .size ()]))
7979 );
8080 }
81- return new FieldFetcher (fieldContexts , unmappedFetchAutomaton , mappedToExclude , includeUnmapped );
81+ return new FieldFetcher (fieldContexts , unmappedFetchAutomaton , includeUnmapped );
8282 }
8383
84- private final List < FieldContext > fieldContexts ;
84+ private final Map < String , FieldContext > fieldContexts ;
8585 private final CharacterRunAutomaton unmappedFetchAutomaton ;
86- private final Set <String > mappedToExclude ;
8786 private final boolean includeUnmapped ;
8887
8988 private FieldFetcher (
90- List < FieldContext > fieldContexts ,
89+ Map < String , FieldContext > fieldContexts ,
9190 CharacterRunAutomaton unmappedFetchAutomaton ,
92- Set <String > mappedToExclude ,
9391 boolean includeUnmapped
9492 ) {
9593 this .fieldContexts = fieldContexts ;
9694 this .unmappedFetchAutomaton = unmappedFetchAutomaton ;
97- this .mappedToExclude = mappedToExclude ;
9895 this .includeUnmapped = includeUnmapped ;
9996 }
10097
10198 public Map <String , DocumentField > fetch (SourceLookup sourceLookup , Set <String > ignoredFields ) throws IOException {
10299 Map <String , DocumentField > documentFields = new HashMap <>();
103- for (FieldContext context : fieldContexts ) {
100+ for (FieldContext context : fieldContexts . values () ) {
104101 String field = context .fieldName ;
105102 if (ignoredFields .contains (field )) {
106103 continue ;
@@ -141,7 +138,7 @@ private void collectUnmapped(Map<String, DocumentField> documentFields, Map<Stri
141138 collectUnmappedList (documentFields , (List <?>) value , currentPath , currentState );
142139 } else {
143140 // we have a leaf value
144- if (this .unmappedFetchAutomaton .isAccept (currentState ) && this .mappedToExclude . contains (currentPath ) == false ) {
141+ if (this .unmappedFetchAutomaton .isAccept (currentState ) && this .fieldContexts . containsKey (currentPath ) == false ) {
145142 if (value != null ) {
146143 DocumentField currentEntry = documentFields .get (currentPath );
147144 if (currentEntry == null ) {
@@ -170,7 +167,7 @@ private void collectUnmappedList(Map<String, DocumentField> documentFields, Iter
170167 } else if (value instanceof List ) {
171168 // weird case, but can happen for objects with "enabled" : "false"
172169 collectUnmappedList (documentFields , (List <?>) value , parentPath , lastState );
173- } else if (this .unmappedFetchAutomaton .isAccept (lastState ) && this .mappedToExclude . contains (parentPath ) == false ) {
170+ } else if (this .unmappedFetchAutomaton .isAccept (lastState ) && this .fieldContexts . containsKey (parentPath ) == false ) {
174171 list .add (value );
175172 }
176173 }
@@ -192,7 +189,7 @@ private static int step(CharacterRunAutomaton automaton, String key, int state)
192189 }
193190
194191 public void setNextReader (LeafReaderContext readerContext ) {
195- for (FieldContext field : fieldContexts ) {
192+ for (FieldContext field : fieldContexts . values () ) {
196193 field .valueFetcher .setNextReader (readerContext );
197194 }
198195 }
0 commit comments