19
19
import org .elasticsearch .common .settings .Settings ;
20
20
import org .elasticsearch .common .xcontent .support .XContentMapValues ;
21
21
import org .elasticsearch .index .IndexMode ;
22
+ import org .elasticsearch .index .IndexVersion ;
23
+ import org .elasticsearch .index .IndexVersions ;
22
24
import org .elasticsearch .index .fielddata .FieldData ;
23
25
import org .elasticsearch .index .fielddata .FieldDataContext ;
24
26
import org .elasticsearch .index .fielddata .IndexFieldData ;
32
34
import org .elasticsearch .index .mapper .BlockDocValuesReader ;
33
35
import org .elasticsearch .index .mapper .BlockLoader ;
34
36
import org .elasticsearch .index .mapper .BlockSourceReader ;
37
+ import org .elasticsearch .index .mapper .CompositeSyntheticFieldLoader ;
35
38
import org .elasticsearch .index .mapper .DocumentParserContext ;
36
39
import org .elasticsearch .index .mapper .FallbackSyntheticSourceBlockLoader ;
37
40
import org .elasticsearch .index .mapper .FieldMapper ;
40
43
import org .elasticsearch .index .mapper .NumberFieldMapper ;
41
44
import org .elasticsearch .index .mapper .SimpleMappedFieldType ;
42
45
import org .elasticsearch .index .mapper .SortedNumericDocValuesSyntheticFieldLoader ;
46
+ import org .elasticsearch .index .mapper .SortedNumericWithOffsetsDocValuesSyntheticFieldLoaderLayer ;
47
+ import org .elasticsearch .index .mapper .SourceLoader ;
43
48
import org .elasticsearch .index .mapper .SourceValueFetcher ;
44
49
import org .elasticsearch .index .mapper .TextSearchInfo ;
45
50
import org .elasticsearch .index .mapper .TimeSeriesParams ;
67
72
import java .util .Objects ;
68
73
import java .util .Set ;
69
74
75
+ import static org .elasticsearch .index .mapper .FieldArrayContext .getOffsetsFieldName ;
76
+
70
77
/** A {@link FieldMapper} for scaled floats. Values are internally multiplied
71
78
* by a scaling factor and rounded to the closest long. */
72
79
public class ScaledFloatFieldMapper extends FieldMapper {
@@ -125,12 +132,34 @@ public static class Builder extends FieldMapper.Builder {
125
132
private final Parameter <TimeSeriesParams .MetricType > metric ;
126
133
127
134
private final IndexMode indexMode ;
135
+ private final IndexVersion indexCreatedVersion ;
136
+ private final SourceKeepMode indexSourceKeepMode ;
128
137
129
- public Builder (String name , Settings settings , IndexMode indexMode ) {
130
- this (name , IGNORE_MALFORMED_SETTING .get (settings ), COERCE_SETTING .get (settings ), indexMode );
138
+ public Builder (
139
+ String name ,
140
+ Settings settings ,
141
+ IndexMode indexMode ,
142
+ IndexVersion indexCreatedVersion ,
143
+ SourceKeepMode indexSourceKeepMode
144
+ ) {
145
+ this (
146
+ name ,
147
+ IGNORE_MALFORMED_SETTING .get (settings ),
148
+ COERCE_SETTING .get (settings ),
149
+ indexMode ,
150
+ indexCreatedVersion ,
151
+ indexSourceKeepMode
152
+ );
131
153
}
132
154
133
- public Builder (String name , boolean ignoreMalformedByDefault , boolean coerceByDefault , IndexMode indexMode ) {
155
+ public Builder (
156
+ String name ,
157
+ boolean ignoreMalformedByDefault ,
158
+ boolean coerceByDefault ,
159
+ IndexMode indexMode ,
160
+ IndexVersion indexCreatedVersion ,
161
+ SourceKeepMode indexSourceKeepMode
162
+ ) {
134
163
super (name );
135
164
this .ignoreMalformed = Parameter .explicitBoolParam (
136
165
"ignore_malformed" ,
@@ -159,6 +188,8 @@ public Builder(String name, boolean ignoreMalformedByDefault, boolean coerceByDe
159
188
);
160
189
}
161
190
});
191
+ this .indexCreatedVersion = indexCreatedVersion ;
192
+ this .indexSourceKeepMode = indexSourceKeepMode ;
162
193
}
163
194
164
195
Builder scalingFactor (double scalingFactor ) {
@@ -200,11 +231,35 @@ public ScaledFloatFieldMapper build(MapperBuilderContext context) {
200
231
coerce .getValue ().value (),
201
232
context .isSourceSynthetic ()
202
233
);
203
- return new ScaledFloatFieldMapper (leafName (), type , builderParams (this , context ), context .isSourceSynthetic (), this );
234
+ String offsetsFieldName = getOffsetsFieldName (
235
+ context ,
236
+ indexSourceKeepMode ,
237
+ hasDocValues .getValue (),
238
+ stored .getValue (),
239
+ this ,
240
+ indexCreatedVersion ,
241
+ IndexVersions .SYNTHETIC_SOURCE_STORE_ARRAYS_NATIVELY_SCALED_FLOAT
242
+ );
243
+ return new ScaledFloatFieldMapper (
244
+ leafName (),
245
+ type ,
246
+ builderParams (this , context ),
247
+ context .isSourceSynthetic (),
248
+ this ,
249
+ offsetsFieldName
250
+ );
204
251
}
205
252
}
206
253
207
- public static final TypeParser PARSER = new TypeParser ((n , c ) -> new Builder (n , c .getSettings (), c .getIndexSettings ().getMode ()));
254
+ public static final TypeParser PARSER = new TypeParser (
255
+ (n , c ) -> new Builder (
256
+ n ,
257
+ c .getSettings (),
258
+ c .getIndexSettings ().getMode (),
259
+ c .indexVersionCreated (),
260
+ c .getIndexSettings ().sourceKeepMode ()
261
+ )
262
+ );
208
263
209
264
public static final class ScaledFloatFieldType extends SimpleMappedFieldType {
210
265
@@ -533,12 +588,17 @@ public String toString() {
533
588
private final TimeSeriesParams .MetricType metricType ;
534
589
private final IndexMode indexMode ;
535
590
591
+ private final IndexVersion indexCreatedVersion ;
592
+ private final String offsetsFieldName ;
593
+ private final SourceKeepMode indexSourceKeepMode ;
594
+
536
595
private ScaledFloatFieldMapper (
537
596
String simpleName ,
538
597
ScaledFloatFieldType mappedFieldType ,
539
598
BuilderParams builderParams ,
540
599
boolean isSourceSynthetic ,
541
- Builder builder
600
+ Builder builder ,
601
+ String offsetsFieldName
542
602
) {
543
603
super (simpleName , mappedFieldType , builderParams );
544
604
this .isSourceSynthetic = isSourceSynthetic ;
@@ -553,6 +613,9 @@ private ScaledFloatFieldMapper(
553
613
this .coerceByDefault = builder .coerce .getDefaultValue ().value ();
554
614
this .metricType = builder .metric .getValue ();
555
615
this .indexMode = builder .indexMode ;
616
+ this .indexCreatedVersion = builder .indexCreatedVersion ;
617
+ this .offsetsFieldName = offsetsFieldName ;
618
+ this .indexSourceKeepMode = builder .indexSourceKeepMode ;
556
619
}
557
620
558
621
boolean coerce () {
@@ -564,6 +627,11 @@ public boolean ignoreMalformed() {
564
627
return ignoreMalformed .value ();
565
628
}
566
629
630
+ @ Override
631
+ public String getOffsetFieldName () {
632
+ return offsetsFieldName ;
633
+ }
634
+
567
635
@ Override
568
636
public ScaledFloatFieldType fieldType () {
569
637
return (ScaledFloatFieldType ) super .fieldType ();
@@ -576,7 +644,9 @@ protected String contentType() {
576
644
577
645
@ Override
578
646
public FieldMapper .Builder getMergeBuilder () {
579
- return new Builder (leafName (), ignoreMalformedByDefault , coerceByDefault , indexMode ).metric (metricType ).init (this );
647
+ return new Builder (leafName (), ignoreMalformedByDefault , coerceByDefault , indexMode , indexCreatedVersion , indexSourceKeepMode )
648
+ .metric (metricType )
649
+ .init (this );
580
650
}
581
651
582
652
@ Override
@@ -606,11 +676,16 @@ protected void parseCreateField(DocumentParserContext context) throws IOExceptio
606
676
value = numericValue ;
607
677
}
608
678
679
+ boolean shouldStoreOffsets = offsetsFieldName != null && context .isImmediateParentAnArray () && context .canAddIgnoredField ();
680
+
609
681
if (value == null ) {
610
682
value = nullValue ;
611
683
}
612
684
613
685
if (value == null ) {
686
+ if (shouldStoreOffsets ) {
687
+ context .getOffSetContext ().recordNull (offsetsFieldName );
688
+ }
614
689
return ;
615
690
}
616
691
@@ -636,6 +711,10 @@ protected void parseCreateField(DocumentParserContext context) throws IOExceptio
636
711
637
712
NumberFieldMapper .NumberType .LONG .addFields (context .doc (), fieldType ().name (), scaledValue , indexed , hasDocValues , stored );
638
713
714
+ if (shouldStoreOffsets ) {
715
+ context .getOffSetContext ().recordOffset (offsetsFieldName , scaledValue );
716
+ }
717
+
639
718
if (hasDocValues == false && (indexed || stored )) {
640
719
context .addToFieldNames (fieldType ().name ());
641
720
}
@@ -777,17 +856,34 @@ public int docValueCount() {
777
856
}
778
857
}
779
858
859
+ private SourceLoader .SyntheticFieldLoader docValuesSyntheticFieldLoader () {
860
+ if (offsetsFieldName != null ) {
861
+ var layers = new ArrayList <CompositeSyntheticFieldLoader .Layer >(2 );
862
+ layers .add (
863
+ new SortedNumericWithOffsetsDocValuesSyntheticFieldLoaderLayer (
864
+ fullPath (),
865
+ offsetsFieldName ,
866
+ (b , value ) -> b .value (decodeForSyntheticSource (value , scalingFactor ))
867
+ )
868
+ );
869
+ if (ignoreMalformed .value ()) {
870
+ layers .add (new CompositeSyntheticFieldLoader .MalformedValuesLayer (fullPath ()));
871
+ }
872
+ return new CompositeSyntheticFieldLoader (leafName (), fullPath (), layers );
873
+ } else {
874
+ return new SortedNumericDocValuesSyntheticFieldLoader (fullPath (), leafName (), ignoreMalformed .value ()) {
875
+ @ Override
876
+ protected void writeValue (XContentBuilder b , long value ) throws IOException {
877
+ b .value (decodeForSyntheticSource (value , scalingFactor ));
878
+ }
879
+ };
880
+ }
881
+ }
882
+
780
883
@ Override
781
884
protected SyntheticSourceSupport syntheticSourceSupport () {
782
885
if (hasDocValues ) {
783
- return new SyntheticSourceSupport .Native (
784
- () -> new SortedNumericDocValuesSyntheticFieldLoader (fullPath (), leafName (), ignoreMalformed .value ()) {
785
- @ Override
786
- protected void writeValue (XContentBuilder b , long value ) throws IOException {
787
- b .value (decodeForSyntheticSource (value , scalingFactor ));
788
- }
789
- }
790
- );
886
+ return new SyntheticSourceSupport .Native (this ::docValuesSyntheticFieldLoader );
791
887
}
792
888
793
889
return super .syntheticSourceSupport ();
0 commit comments