18
18
import org .elasticsearch .common .Explicit ;
19
19
import org .elasticsearch .common .Strings ;
20
20
import org .elasticsearch .common .bytes .BytesReference ;
21
+ import org .elasticsearch .common .settings .Setting ;
21
22
import org .elasticsearch .common .settings .Settings ;
22
23
import org .elasticsearch .common .util .CollectionUtils ;
23
24
import org .elasticsearch .core .Nullable ;
24
25
import org .elasticsearch .features .NodeFeature ;
25
26
import org .elasticsearch .index .IndexMode ;
27
+ import org .elasticsearch .index .IndexSettings ;
26
28
import org .elasticsearch .index .IndexVersions ;
27
29
import org .elasticsearch .index .query .QueryShardException ;
28
30
import org .elasticsearch .index .query .SearchExecutionContext ;
@@ -62,8 +64,16 @@ public class SourceFieldMapper extends MetadataFieldMapper {
62
64
63
65
public static final String LOSSY_PARAMETERS_ALLOWED_SETTING_NAME = "index.lossy.source-mapping-parameters" ;
64
66
67
+ public static final Setting <Mode > INDEX_MAPPER_SOURCE_MODE_SETTING = Setting .enumSetting (SourceFieldMapper .Mode .class , settings -> {
68
+ final IndexMode indexMode = IndexSettings .MODE .get (settings );
69
+ return switch (indexMode ) {
70
+ case IndexMode .LOGSDB , IndexMode .TIME_SERIES -> Mode .SYNTHETIC .name ();
71
+ default -> Mode .STORED .name ();
72
+ };
73
+ }, "index.mapping.source.mode" , value -> {}, Setting .Property .Final , Setting .Property .IndexScope );
74
+
65
75
/** The source mode */
66
- private enum Mode {
76
+ public enum Mode {
67
77
DISABLED ,
68
78
STORED ,
69
79
SYNTHETIC
@@ -96,6 +106,15 @@ private enum Mode {
96
106
true
97
107
);
98
108
109
+ private static final SourceFieldMapper TSDB_DEFAULT_STORED = new SourceFieldMapper (
110
+ Mode .STORED ,
111
+ Explicit .IMPLICIT_TRUE ,
112
+ Strings .EMPTY_ARRAY ,
113
+ Strings .EMPTY_ARRAY ,
114
+ IndexMode .TIME_SERIES ,
115
+ true
116
+ );
117
+
99
118
private static final SourceFieldMapper TSDB_DEFAULT_NO_RECOVERY_SOURCE = new SourceFieldMapper (
100
119
Mode .SYNTHETIC ,
101
120
Explicit .IMPLICIT_TRUE ,
@@ -105,6 +124,15 @@ private enum Mode {
105
124
false
106
125
);
107
126
127
+ private static final SourceFieldMapper TSDB_DEFAULT_NO_RECOVERY_SOURCE_STORED = new SourceFieldMapper (
128
+ Mode .STORED ,
129
+ Explicit .IMPLICIT_TRUE ,
130
+ Strings .EMPTY_ARRAY ,
131
+ Strings .EMPTY_ARRAY ,
132
+ IndexMode .TIME_SERIES ,
133
+ false
134
+ );
135
+
108
136
private static final SourceFieldMapper LOGSDB_DEFAULT = new SourceFieldMapper (
109
137
Mode .SYNTHETIC ,
110
138
Explicit .IMPLICIT_TRUE ,
@@ -114,6 +142,15 @@ private enum Mode {
114
142
true
115
143
);
116
144
145
+ private static final SourceFieldMapper LOGSDB_DEFAULT_STORED = new SourceFieldMapper (
146
+ Mode .STORED ,
147
+ Explicit .IMPLICIT_TRUE ,
148
+ Strings .EMPTY_ARRAY ,
149
+ Strings .EMPTY_ARRAY ,
150
+ IndexMode .LOGSDB ,
151
+ true
152
+ );
153
+
117
154
private static final SourceFieldMapper LOGSDB_DEFAULT_NO_RECOVERY_SOURCE = new SourceFieldMapper (
118
155
Mode .SYNTHETIC ,
119
156
Explicit .IMPLICIT_TRUE ,
@@ -123,6 +160,15 @@ private enum Mode {
123
160
false
124
161
);
125
162
163
+ private static final SourceFieldMapper LOGSDB_DEFAULT_NO_RECOVERY_SOURCE_STORED = new SourceFieldMapper (
164
+ Mode .STORED ,
165
+ Explicit .IMPLICIT_TRUE ,
166
+ Strings .EMPTY_ARRAY ,
167
+ Strings .EMPTY_ARRAY ,
168
+ IndexMode .LOGSDB ,
169
+ false
170
+ );
171
+
126
172
/*
127
173
* Synthetic source was added as the default for TSDB in v.8.7. The legacy field mapper below
128
174
* is used in bwc tests and mixed clusters containing time series indexes created in an earlier version.
@@ -197,6 +243,8 @@ public static class Builder extends MetadataFieldMapper.Builder {
197
243
m -> Arrays .asList (toType (m ).excludes )
198
244
);
199
245
246
+ private final Settings settings ;
247
+
200
248
private final IndexMode indexMode ;
201
249
202
250
private final boolean supportsNonDefaultParameterValues ;
@@ -210,6 +258,7 @@ public Builder(
210
258
boolean enableRecoverySource
211
259
) {
212
260
super (Defaults .NAME );
261
+ this .settings = settings ;
213
262
this .indexMode = indexMode ;
214
263
this .supportsNonDefaultParameterValues = supportsCheckForNonDefaultParams == false
215
264
|| settings .getAsBoolean (LOSSY_PARAMETERS_ALLOWED_SETTING_NAME , true );
@@ -226,10 +275,10 @@ protected Parameter<?>[] getParameters() {
226
275
return new Parameter <?>[] { enabled , mode , includes , excludes };
227
276
}
228
277
229
- private boolean isDefault () {
230
- Mode m = mode . get ();
231
- if ( m != null
232
- && ((( indexMode != null && indexMode . isSyntheticSourceEnabled () && m == Mode . SYNTHETIC ) == false ) || m == Mode .DISABLED )) {
278
+ private boolean isDefault (final Mode sourceMode ) {
279
+ if ( sourceMode != null
280
+ && ((( indexMode != null && indexMode . isSyntheticSourceEnabled () && sourceMode == Mode . SYNTHETIC ) == false )
281
+ || sourceMode == Mode .DISABLED )) {
233
282
return false ;
234
283
}
235
284
return enabled .get ().value () && includes .getValue ().isEmpty () && excludes .getValue ().isEmpty ();
@@ -242,12 +291,14 @@ public SourceFieldMapper build() {
242
291
throw new MapperParsingException ("Cannot set both [mode] and [enabled] parameters" );
243
292
}
244
293
}
245
- if (isDefault ()) {
246
- return switch (indexMode ) {
247
- case TIME_SERIES -> enableRecoverySource ? TSDB_DEFAULT : TSDB_DEFAULT_NO_RECOVERY_SOURCE ;
248
- case LOGSDB -> enableRecoverySource ? LOGSDB_DEFAULT : LOGSDB_DEFAULT_NO_RECOVERY_SOURCE ;
249
- default -> enableRecoverySource ? DEFAULT : DEFAULT_NO_RECOVERY_SOURCE ;
250
- };
294
+ // NOTE: if the `index.mapper.source.mode` exists it takes precedence to determine the source mode for `_source`
295
+ // otherwise the mode is determined according to `index.mode` and `_source.mode`.
296
+ final Mode sourceMode = INDEX_MAPPER_SOURCE_MODE_SETTING .exists (settings )
297
+ ? INDEX_MAPPER_SOURCE_MODE_SETTING .get (settings )
298
+ : mode .get ();
299
+ if (isDefault (sourceMode )) {
300
+ return resolveSourceMode (indexMode , sourceMode , enableRecoverySource );
301
+
251
302
}
252
303
if (supportsNonDefaultParameterValues == false ) {
253
304
List <String > disallowed = new ArrayList <>();
@@ -271,8 +322,9 @@ public SourceFieldMapper build() {
271
322
);
272
323
}
273
324
}
325
+
274
326
SourceFieldMapper sourceFieldMapper = new SourceFieldMapper (
275
- mode . get () ,
327
+ sourceMode ,
276
328
enabled .get (),
277
329
includes .getValue ().toArray (Strings .EMPTY_ARRAY ),
278
330
excludes .getValue ().toArray (Strings .EMPTY_ARRAY ),
@@ -287,21 +339,39 @@ public SourceFieldMapper build() {
287
339
288
340
}
289
341
342
+ private static SourceFieldMapper resolveSourceMode (final IndexMode indexMode , final Mode sourceMode , boolean enableRecoverySource ) {
343
+ if (indexMode == IndexMode .STANDARD ) {
344
+ return enableRecoverySource ? DEFAULT : DEFAULT_NO_RECOVERY_SOURCE ;
345
+ }
346
+ final SourceFieldMapper syntheticWithoutRecoverySource = indexMode == IndexMode .TIME_SERIES
347
+ ? TSDB_DEFAULT_NO_RECOVERY_SOURCE
348
+ : LOGSDB_DEFAULT_NO_RECOVERY_SOURCE ;
349
+ final SourceFieldMapper syntheticWithRecoverySource = indexMode == IndexMode .TIME_SERIES ? TSDB_DEFAULT : LOGSDB_DEFAULT ;
350
+ final SourceFieldMapper storedWithoutRecoverySource = indexMode == IndexMode .TIME_SERIES
351
+ ? TSDB_DEFAULT_NO_RECOVERY_SOURCE_STORED
352
+ : LOGSDB_DEFAULT_NO_RECOVERY_SOURCE_STORED ;
353
+ final SourceFieldMapper storedWithRecoverySource = indexMode == IndexMode .TIME_SERIES ? TSDB_DEFAULT_STORED : LOGSDB_DEFAULT_STORED ;
354
+
355
+ return switch (sourceMode ) {
356
+ case SYNTHETIC -> enableRecoverySource ? syntheticWithRecoverySource : syntheticWithoutRecoverySource ;
357
+ case STORED -> enableRecoverySource ? storedWithRecoverySource : storedWithoutRecoverySource ;
358
+ case DISABLED -> throw new IllegalArgumentException (
359
+ "_source can not be disabled in index using [" + indexMode + "] index mode"
360
+ );
361
+ };
362
+ }
363
+
290
364
public static final TypeParser PARSER = new ConfigurableTypeParser (c -> {
291
- var indexMode = c .getIndexSettings ().getMode ();
365
+ final IndexMode indexMode = c .getIndexSettings ().getMode ();
292
366
boolean enableRecoverySource = INDICES_RECOVERY_SOURCE_ENABLED_SETTING .get (c .getSettings ());
367
+ final Mode settingSourceMode = INDEX_MAPPER_SOURCE_MODE_SETTING .get (c .getSettings ());
368
+
293
369
if (indexMode .isSyntheticSourceEnabled ()) {
294
- if (indexMode == IndexMode .TIME_SERIES ) {
295
- if (c .getIndexSettings ().getIndexVersionCreated ().onOrAfter (IndexVersions .V_8_7_0 )) {
296
- return enableRecoverySource ? TSDB_DEFAULT : TSDB_DEFAULT_NO_RECOVERY_SOURCE ;
297
- } else {
298
- return enableRecoverySource ? TSDB_LEGACY_DEFAULT : TSDB_LEGACY_DEFAULT_NO_RECOVERY_SOURCE ;
299
- }
300
- } else if (indexMode == IndexMode .LOGSDB ) {
301
- return enableRecoverySource ? LOGSDB_DEFAULT : LOGSDB_DEFAULT_NO_RECOVERY_SOURCE ;
370
+ if (indexMode == IndexMode .TIME_SERIES && c .getIndexSettings ().getIndexVersionCreated ().before (IndexVersions .V_8_7_0 )) {
371
+ return enableRecoverySource ? TSDB_LEGACY_DEFAULT : TSDB_LEGACY_DEFAULT_NO_RECOVERY_SOURCE ;
302
372
}
303
373
}
304
- return enableRecoverySource ? DEFAULT : DEFAULT_NO_RECOVERY_SOURCE ;
374
+ return resolveSourceMode ( indexMode , settingSourceMode , enableRecoverySource ) ;
305
375
},
306
376
c -> new Builder (
307
377
c .getIndexSettings ().getMode (),
0 commit comments