11
11
12
12
import org .apache .lucene .document .Field ;
13
13
import org .apache .lucene .document .SortedSetDocValuesField ;
14
+ import org .apache .lucene .document .StoredField ;
14
15
import org .apache .lucene .document .StringField ;
15
16
import org .apache .lucene .index .IndexWriter ;
16
17
import org .apache .lucene .index .IndexableField ;
17
18
import org .apache .lucene .util .BytesRef ;
18
19
import org .elasticsearch .common .xcontent .XContentParserUtils ;
19
20
import org .elasticsearch .index .mapper .ContentPath ;
20
21
import org .elasticsearch .index .mapper .DocumentParserContext ;
21
- import org .elasticsearch .index .mapper .IgnoredSourceFieldMapper ;
22
22
import org .elasticsearch .index .mapper .MappedFieldType ;
23
- import org .elasticsearch .index .mapper .XContentDataHelper ;
24
- import org .elasticsearch .xcontent .CopyingXContentParser ;
25
- import org .elasticsearch .xcontent .XContentBuilder ;
26
23
import org .elasticsearch .xcontent .XContentParser ;
27
24
28
25
import java .io .IOException ;
@@ -39,6 +36,7 @@ class FlattenedFieldParser {
39
36
40
37
private final String rootFieldFullPath ;
41
38
private final String keyedFieldFullPath ;
39
+ private final String keyedIgnoredValuesFieldFullPath ;
42
40
43
41
private final MappedFieldType fieldType ;
44
42
private final int depthLimit ;
@@ -48,13 +46,15 @@ class FlattenedFieldParser {
48
46
FlattenedFieldParser (
49
47
String rootFieldFullPath ,
50
48
String keyedFieldFullPath ,
49
+ String keyedIgnoredValuesFieldFullPath ,
51
50
MappedFieldType fieldType ,
52
51
int depthLimit ,
53
52
int ignoreAbove ,
54
53
String nullValue
55
54
) {
56
55
this .rootFieldFullPath = rootFieldFullPath ;
57
56
this .keyedFieldFullPath = keyedFieldFullPath ;
57
+ this .keyedIgnoredValuesFieldFullPath = keyedIgnoredValuesFieldFullPath ;
58
58
this .fieldType = fieldType ;
59
59
this .depthLimit = depthLimit ;
60
60
this .ignoreAbove = ignoreAbove ;
@@ -65,36 +65,18 @@ public List<IndexableField> parse(final DocumentParserContext documentParserCont
65
65
XContentParser parser = documentParserContext .parser ();
66
66
XContentParserUtils .ensureExpectedToken (XContentParser .Token .START_OBJECT , parser .currentToken (), parser );
67
67
68
- XContentBuilder rawDataForSyntheticSource = null ;
69
- if (documentParserContext .canAddIgnoredField () && ignoreAbove < Integer .MAX_VALUE ) {
70
- var copyingParser = new CopyingXContentParser (parser );
71
- rawDataForSyntheticSource = copyingParser .getBuilder ();
72
- parser = copyingParser ;
73
- }
74
-
75
68
ContentPath path = new ContentPath ();
76
69
List <IndexableField > fields = new ArrayList <>();
77
70
78
71
var context = new Context (parser , documentParserContext );
79
72
parseObject (context , path , fields );
80
- if (rawDataForSyntheticSource != null && context .isIgnoredValueEncountered ()) {
81
- // One or more inner fields are ignored due to `ignore_above`.
82
- // Because of that we will store whole object as is in order to generate synthetic source.
83
- documentParserContext .addIgnoredField (
84
- IgnoredSourceFieldMapper .NameValue .fromContext (
85
- documentParserContext ,
86
- rootFieldFullPath ,
87
- XContentDataHelper .encodeXContentBuilder (rawDataForSyntheticSource )
88
- )
89
- );
90
- }
91
73
92
74
return fields ;
93
75
}
94
76
95
77
private void parseObject (Context context , ContentPath path , List <IndexableField > fields ) throws IOException {
96
78
String currentName = null ;
97
- XContentParser parser = context .getParser ();
79
+ XContentParser parser = context .parser ();
98
80
while (true ) {
99
81
XContentParser .Token token = parser .nextToken ();
100
82
if (token == XContentParser .Token .END_OBJECT ) {
@@ -111,7 +93,7 @@ private void parseObject(Context context, ContentPath path, List<IndexableField>
111
93
}
112
94
113
95
private void parseArray (Context context , ContentPath path , String currentName , List <IndexableField > fields ) throws IOException {
114
- XContentParser parser = context .getParser ();
96
+ XContentParser parser = context .parser ();
115
97
while (true ) {
116
98
XContentParser .Token token = parser .nextToken ();
117
99
if (token == XContentParser .Token .END_ARRAY ) {
@@ -128,7 +110,7 @@ private void parseFieldValue(
128
110
String currentName ,
129
111
List <IndexableField > fields
130
112
) throws IOException {
131
- XContentParser parser = context .getParser ();
113
+ XContentParser parser = context .parser ();
132
114
if (token == XContentParser .Token .START_OBJECT ) {
133
115
path .add (currentName );
134
116
validateDepthLimit (path );
@@ -151,19 +133,23 @@ private void parseFieldValue(
151
133
}
152
134
153
135
private void addField (Context context , ContentPath path , String currentName , String value , List <IndexableField > fields ) {
154
- if (value .length () > ignoreAbove ) {
155
- context .onIgnoredValue ();
156
- return ;
157
- }
158
-
159
136
String key = path .pathAsText (currentName );
160
137
if (key .contains (SEPARATOR )) {
161
138
throw new IllegalArgumentException (
162
139
"Keys in [flattened] fields cannot contain the reserved character \\ 0. Offending key: [" + key + "]."
163
140
);
164
141
}
142
+
165
143
String keyedValue = createKeyedValue (key , value );
166
144
BytesRef bytesKeyedValue = new BytesRef (keyedValue );
145
+
146
+ if (value .length () > ignoreAbove ) {
147
+ if (context .documentParserContext ().mappingLookup ().isSourceSynthetic ()) {
148
+ fields .add (new StoredField (keyedIgnoredValuesFieldFullPath , bytesKeyedValue ));
149
+ }
150
+ return ;
151
+ }
152
+
167
153
// check the keyed value doesn't exceed the IndexWriter.MAX_TERM_LENGTH limit enforced by Lucene at index time
168
154
// in that case we can already throw a more user friendly exception here which includes the offending fields key and value lengths
169
155
if (bytesKeyedValue .length > IndexWriter .MAX_TERM_LENGTH ) {
@@ -198,10 +184,10 @@ private void addField(Context context, ContentPath path, String currentName, Str
198
184
final String keyedFieldName = FlattenedFieldParser .extractKey (bytesKeyedValue ).utf8ToString ();
199
185
if (fieldType .isDimension () && fieldType .dimensions ().contains (keyedFieldName )) {
200
186
final BytesRef keyedFieldValue = FlattenedFieldParser .extractValue (bytesKeyedValue );
201
- context .getDocumentParserContext ()
187
+ context .documentParserContext ()
202
188
.getDimensions ()
203
189
.addString (rootFieldFullPath + "." + keyedFieldName , keyedFieldValue )
204
- .validate (context .getDocumentParserContext ().indexSettings ());
190
+ .validate (context .documentParserContext ().indexSettings ());
205
191
}
206
192
}
207
193
}
@@ -239,32 +225,5 @@ static BytesRef extractValue(BytesRef keyedValue) {
239
225
return new BytesRef (keyedValue .bytes , valueStart , keyedValue .length - valueStart );
240
226
}
241
227
242
- private static class Context {
243
- private final XContentParser parser ;
244
- private final DocumentParserContext documentParserContext ;
245
-
246
- private boolean ignoredValueEncountered ;
247
-
248
- private Context (XContentParser parser , DocumentParserContext documentParserContext ) {
249
- this .parser = parser ;
250
- this .documentParserContext = documentParserContext ;
251
- this .ignoredValueEncountered = false ;
252
- }
253
-
254
- public XContentParser getParser () {
255
- return parser ;
256
- }
257
-
258
- public DocumentParserContext getDocumentParserContext () {
259
- return documentParserContext ;
260
- }
261
-
262
- public void onIgnoredValue () {
263
- this .ignoredValueEncountered = true ;
264
- }
265
-
266
- public boolean isIgnoredValueEncountered () {
267
- return ignoredValueEncountered ;
268
- }
269
- }
228
+ private record Context (XContentParser parser , DocumentParserContext documentParserContext ) {}
270
229
}
0 commit comments