34
34
import java .util .ArrayList ;
35
35
import java .util .Collection ;
36
36
import java .util .HashMap ;
37
- import java .util .HashSet ;
37
+ import java .util .LinkedHashMap ;
38
38
import java .util .List ;
39
39
import java .util .Map ;
40
40
import java .util .Set ;
@@ -48,9 +48,10 @@ public static FieldFetcher create(QueryShardContext context,
48
48
SearchLookup searchLookup ,
49
49
Collection <FieldAndFormat > fieldAndFormats ) {
50
50
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 <>();
52
54
List <String > unmappedFetchPattern = new ArrayList <>();
53
- Set <String > mappedToExclude = new HashSet <>();
54
55
boolean includeUnmapped = false ;
55
56
56
57
for (FieldAndFormat fieldAndFormat : fieldAndFormats ) {
@@ -68,8 +69,7 @@ public static FieldFetcher create(QueryShardContext context,
68
69
continue ;
69
70
}
70
71
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 ));
73
73
}
74
74
}
75
75
CharacterRunAutomaton unmappedFetchAutomaton = new CharacterRunAutomaton (Automata .makeEmpty ());
@@ -78,29 +78,26 @@ public static FieldFetcher create(QueryShardContext context,
78
78
Regex .simpleMatchToAutomaton (unmappedFetchPattern .toArray (new String [unmappedFetchPattern .size ()]))
79
79
);
80
80
}
81
- return new FieldFetcher (fieldContexts , unmappedFetchAutomaton , mappedToExclude , includeUnmapped );
81
+ return new FieldFetcher (fieldContexts , unmappedFetchAutomaton , includeUnmapped );
82
82
}
83
83
84
- private final List < FieldContext > fieldContexts ;
84
+ private final Map < String , FieldContext > fieldContexts ;
85
85
private final CharacterRunAutomaton unmappedFetchAutomaton ;
86
- private final Set <String > mappedToExclude ;
87
86
private final boolean includeUnmapped ;
88
87
89
88
private FieldFetcher (
90
- List < FieldContext > fieldContexts ,
89
+ Map < String , FieldContext > fieldContexts ,
91
90
CharacterRunAutomaton unmappedFetchAutomaton ,
92
- Set <String > mappedToExclude ,
93
91
boolean includeUnmapped
94
92
) {
95
93
this .fieldContexts = fieldContexts ;
96
94
this .unmappedFetchAutomaton = unmappedFetchAutomaton ;
97
- this .mappedToExclude = mappedToExclude ;
98
95
this .includeUnmapped = includeUnmapped ;
99
96
}
100
97
101
98
public Map <String , DocumentField > fetch (SourceLookup sourceLookup , Set <String > ignoredFields ) throws IOException {
102
99
Map <String , DocumentField > documentFields = new HashMap <>();
103
- for (FieldContext context : fieldContexts ) {
100
+ for (FieldContext context : fieldContexts . values () ) {
104
101
String field = context .fieldName ;
105
102
if (ignoredFields .contains (field )) {
106
103
continue ;
@@ -141,7 +138,7 @@ private void collectUnmapped(Map<String, DocumentField> documentFields, Map<Stri
141
138
collectUnmappedList (documentFields , (List <?>) value , currentPath , currentState );
142
139
} else {
143
140
// 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 ) {
145
142
if (value != null ) {
146
143
DocumentField currentEntry = documentFields .get (currentPath );
147
144
if (currentEntry == null ) {
@@ -170,7 +167,7 @@ private void collectUnmappedList(Map<String, DocumentField> documentFields, Iter
170
167
} else if (value instanceof List ) {
171
168
// weird case, but can happen for objects with "enabled" : "false"
172
169
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 ) {
174
171
list .add (value );
175
172
}
176
173
}
@@ -192,7 +189,7 @@ private static int step(CharacterRunAutomaton automaton, String key, int state)
192
189
}
193
190
194
191
public void setNextReader (LeafReaderContext readerContext ) {
195
- for (FieldContext field : fieldContexts ) {
192
+ for (FieldContext field : fieldContexts . values () ) {
196
193
field .valueFetcher .setNextReader (readerContext );
197
194
}
198
195
}
0 commit comments