3737import org .elasticsearch .common .settings .Settings ;
3838import org .elasticsearch .index .IndexMode ;
3939import org .elasticsearch .index .IndexVersion ;
40+ import org .elasticsearch .index .IndexVersions ;
4041import org .elasticsearch .index .fielddata .FieldDataContext ;
4142import org .elasticsearch .index .fielddata .IndexFieldData ;
4243import org .elasticsearch .index .fielddata .IndexNumericFieldData .NumericType ;
7071import java .io .IOException ;
7172import java .math .BigDecimal ;
7273import java .time .ZoneId ;
74+ import java .util .ArrayList ;
7375import java .util .Arrays ;
7476import java .util .Collection ;
7577import java .util .Collections ;
8082import java .util .function .BiFunction ;
8183import java .util .function .Function ;
8284
85+ import static org .elasticsearch .index .mapper .FieldArrayContext .getOffsetsFieldName ;
86+
8387/** A {@link FieldMapper} for numeric types: byte, short, int, long, float and double. */
8488public class NumberFieldMapper extends FieldMapper {
8589
@@ -127,20 +131,31 @@ public static final class Builder extends FieldMapper.DimensionBuilder {
127131 private final IndexVersion indexCreatedVersion ;
128132
129133 private final IndexMode indexMode ;
134+ private final SourceKeepMode indexSourceKeepMode ;
130135
131136 public Builder (
132137 String name ,
133138 NumberType type ,
134139 ScriptCompiler compiler ,
135140 Settings settings ,
136141 IndexVersion indexCreatedVersion ,
137- IndexMode mode
142+ IndexMode mode ,
143+ SourceKeepMode indexSourceKeepMode
138144 ) {
139- this (name , type , compiler , IGNORE_MALFORMED_SETTING .get (settings ), COERCE_SETTING .get (settings ), indexCreatedVersion , mode );
145+ this (
146+ name ,
147+ type ,
148+ compiler ,
149+ IGNORE_MALFORMED_SETTING .get (settings ),
150+ COERCE_SETTING .get (settings ),
151+ indexCreatedVersion ,
152+ mode ,
153+ indexSourceKeepMode
154+ );
140155 }
141156
142157 public static Builder docValuesOnly (String name , NumberType type , IndexVersion indexCreatedVersion ) {
143- Builder builder = new Builder (name , type , ScriptCompiler .NONE , false , false , indexCreatedVersion , null );
158+ Builder builder = new Builder (name , type , ScriptCompiler .NONE , false , false , indexCreatedVersion , null , null );
144159 builder .indexed .setValue (false );
145160 builder .dimension .setValue (false );
146161 return builder ;
@@ -153,7 +168,8 @@ public Builder(
153168 boolean ignoreMalformedByDefault ,
154169 boolean coerceByDefault ,
155170 IndexVersion indexCreatedVersion ,
156- IndexMode mode
171+ IndexMode mode ,
172+ SourceKeepMode indexSourceKeepMode
157173 ) {
158174 super (name );
159175 this .type = type ;
@@ -209,6 +225,8 @@ public Builder(
209225
210226 this .script .precludesParameters (ignoreMalformed , coerce , nullValue );
211227 addScriptValidation (script , indexed , hasDocValues );
228+
229+ this .indexSourceKeepMode = indexSourceKeepMode ;
212230 }
213231
214232 Builder nullValue (Number number ) {
@@ -272,7 +290,16 @@ public NumberFieldMapper build(MapperBuilderContext context) {
272290 MappedFieldType ft = new NumberFieldType (context .buildFullName (leafName ()), this , context .isSourceSynthetic ());
273291 hasScript = script .get () != null ;
274292 onScriptError = onScriptErrorParam .getValue ();
275- return new NumberFieldMapper (leafName (), ft , builderParams (this , context ), context .isSourceSynthetic (), this );
293+ String offsetsFieldName = getOffsetsFieldName (
294+ context ,
295+ indexSourceKeepMode ,
296+ hasDocValues .getValue (),
297+ stored .getValue (),
298+ this ,
299+ indexCreatedVersion ,
300+ IndexVersions .SYNTHETIC_SOURCE_STORE_ARRAYS_NATIVELY_NUMBER
301+ );
302+ return new NumberFieldMapper (leafName (), ft , builderParams (this , context ), context .isSourceSynthetic (), this , offsetsFieldName );
276303 }
277304 }
278305
@@ -445,13 +472,8 @@ private static void validateFiniteValue(float value) {
445472 }
446473
447474 @ Override
448- SourceLoader .SyntheticFieldLoader syntheticFieldLoader (String fieldName , String fieldSimpleName , boolean ignoreMalformed ) {
449- return new SortedNumericDocValuesSyntheticFieldLoader (fieldName , fieldSimpleName , ignoreMalformed ) {
450- @ Override
451- protected void writeValue (XContentBuilder b , long value ) throws IOException {
452- b .value (HalfFloatPoint .sortableShortToHalfFloat ((short ) value ));
453- }
454- };
475+ public void writeValue (XContentBuilder b , long value ) throws IOException {
476+ b .value (HalfFloatPoint .sortableShortToHalfFloat ((short ) value ));
455477 }
456478
457479 @ Override
@@ -634,13 +656,8 @@ private static void validateFiniteValue(float value) {
634656 }
635657
636658 @ Override
637- SourceLoader .SyntheticFieldLoader syntheticFieldLoader (String fieldName , String fieldSimpleName , boolean ignoreMalformed ) {
638- return new SortedNumericDocValuesSyntheticFieldLoader (fieldName , fieldSimpleName , ignoreMalformed ) {
639- @ Override
640- protected void writeValue (XContentBuilder b , long value ) throws IOException {
641- b .value (NumericUtils .sortableIntToFloat ((int ) value ));
642- }
643- };
659+ public void writeValue (XContentBuilder b , long value ) throws IOException {
660+ b .value (NumericUtils .sortableIntToFloat ((int ) value ));
644661 }
645662
646663 @ Override
@@ -789,13 +806,8 @@ private static void validateParsed(double value) {
789806 }
790807
791808 @ Override
792- SourceLoader .SyntheticFieldLoader syntheticFieldLoader (String fieldName , String fieldSimpleName , boolean ignoreMalformed ) {
793- return new SortedNumericDocValuesSyntheticFieldLoader (fieldName , fieldSimpleName , ignoreMalformed ) {
794- @ Override
795- protected void writeValue (XContentBuilder b , long value ) throws IOException {
796- b .value (NumericUtils .sortableLongToDouble (value ));
797- }
798- };
809+ public void writeValue (XContentBuilder b , long value ) throws IOException {
810+ b .value (NumericUtils .sortableLongToDouble (value ));
799811 }
800812
801813 @ Override
@@ -838,12 +850,12 @@ public Number parsePoint(byte[] value) {
838850 }
839851
840852 @ Override
841- public Short parse (XContentParser parser , boolean coerce ) throws IOException {
853+ public Byte parse (XContentParser parser , boolean coerce ) throws IOException {
842854 int value = parser .intValue (coerce );
843855 if (value < Byte .MIN_VALUE || value > Byte .MAX_VALUE ) {
844856 throw new IllegalArgumentException ("Value [" + value + "] is out of range for a byte" );
845857 }
846- return (short ) value ;
858+ return (byte ) value ;
847859 }
848860
849861 @ Override
@@ -912,8 +924,8 @@ public IndexFieldData.Builder getValueFetcherFieldDataBuilder(
912924 }
913925
914926 @ Override
915- SourceLoader . SyntheticFieldLoader syntheticFieldLoader ( String fieldName , String fieldSimpleName , boolean ignoreMalformed ) {
916- return NumberType . syntheticLongFieldLoader ( fieldName , fieldSimpleName , ignoreMalformed );
927+ public void writeValue ( XContentBuilder b , long value ) throws IOException {
928+ b . value ( value );
917929 }
918930
919931 @ Override
@@ -1030,8 +1042,8 @@ public IndexFieldData.Builder getValueFetcherFieldDataBuilder(
10301042 }
10311043
10321044 @ Override
1033- SourceLoader . SyntheticFieldLoader syntheticFieldLoader ( String fieldName , String fieldSimpleName , boolean ignoreMalformed ) {
1034- return NumberType . syntheticLongFieldLoader ( fieldName , fieldSimpleName , ignoreMalformed );
1045+ public void writeValue ( XContentBuilder b , long value ) throws IOException {
1046+ b . value ( value );
10351047 }
10361048
10371049 @ Override
@@ -1222,8 +1234,8 @@ public IndexFieldData.Builder getValueFetcherFieldDataBuilder(
12221234 }
12231235
12241236 @ Override
1225- SourceLoader . SyntheticFieldLoader syntheticFieldLoader ( String fieldName , String fieldSimpleName , boolean ignoreMalformed ) {
1226- return NumberType . syntheticLongFieldLoader ( fieldName , fieldSimpleName , ignoreMalformed );
1237+ public void writeValue ( XContentBuilder b , long value ) throws IOException {
1238+ b . value ( value );
12271239 }
12281240
12291241 @ Override
@@ -1374,8 +1386,8 @@ public IndexFieldData.Builder getValueFetcherFieldDataBuilder(
13741386 }
13751387
13761388 @ Override
1377- SourceLoader . SyntheticFieldLoader syntheticFieldLoader ( String fieldName , String fieldSimpleName , boolean ignoreMalformed ) {
1378- return syntheticLongFieldLoader ( fieldName , fieldSimpleName , ignoreMalformed );
1389+ public void writeValue ( XContentBuilder b , long value ) throws IOException {
1390+ b . value ( value );
13791391 }
13801392
13811393 @ Override
@@ -1427,7 +1439,15 @@ private boolean isOutOfRange(Object value) {
14271439 this .name = name ;
14281440 this .numericType = numericType ;
14291441 this .parser = createTypeParserWithLegacySupport (
1430- (n , c ) -> new Builder (n , this , c .scriptCompiler (), c .getSettings (), c .indexVersionCreated (), c .getIndexSettings ().getMode ())
1442+ (n , c ) -> new Builder (
1443+ n ,
1444+ this ,
1445+ c .scriptCompiler (),
1446+ c .getSettings (),
1447+ c .indexVersionCreated (),
1448+ c .getIndexSettings ().getMode (),
1449+ c .getIndexSettings ().sourceKeepMode ()
1450+ )
14311451 );
14321452 }
14331453
@@ -1658,17 +1678,13 @@ public double reduceToStoredPrecision(double value) {
16581678 return ((Number ) value ).doubleValue ();
16591679 }
16601680
1661- abstract SourceLoader . SyntheticFieldLoader syntheticFieldLoader ( String fieldName , String fieldSimpleName , boolean ignoreMalformed ) ;
1681+ abstract void writeValue ( XContentBuilder builder , long longValue ) throws IOException ;
16621682
1663- private static SourceLoader .SyntheticFieldLoader syntheticLongFieldLoader (
1664- String fieldName ,
1665- String fieldSimpleName ,
1666- boolean ignoreMalformed
1667- ) {
1683+ SourceLoader .SyntheticFieldLoader syntheticFieldLoader (String fieldName , String fieldSimpleName , boolean ignoreMalformed ) {
16681684 return new SortedNumericDocValuesSyntheticFieldLoader (fieldName , fieldSimpleName , ignoreMalformed ) {
16691685 @ Override
1670- protected void writeValue (XContentBuilder b , long value ) throws IOException {
1671- b . value ( value );
1686+ public void writeValue (XContentBuilder b , long value ) throws IOException {
1687+ NumberType . this . writeValue ( b , value );
16721688 }
16731689 };
16741690 }
@@ -2036,15 +2052,18 @@ public MetricType getMetricType() {
20362052 private boolean allowMultipleValues ;
20372053 private final IndexVersion indexCreatedVersion ;
20382054 private final boolean isSyntheticSource ;
2055+ private final String offsetsFieldName ;
20392056
20402057 private final IndexMode indexMode ;
2058+ private final SourceKeepMode indexSourceKeepMode ;
20412059
20422060 private NumberFieldMapper (
20432061 String simpleName ,
20442062 MappedFieldType mappedFieldType ,
20452063 BuilderParams builderParams ,
20462064 boolean isSyntheticSource ,
2047- Builder builder
2065+ Builder builder ,
2066+ String offsetsFieldName
20482067 ) {
20492068 super (simpleName , mappedFieldType , builderParams );
20502069 this .type = builder .type ;
@@ -2065,6 +2084,8 @@ private NumberFieldMapper(
20652084 this .indexCreatedVersion = builder .indexCreatedVersion ;
20662085 this .isSyntheticSource = isSyntheticSource ;
20672086 this .indexMode = builder .indexMode ;
2087+ this .offsetsFieldName = offsetsFieldName ;
2088+ this .indexSourceKeepMode = builder .indexSourceKeepMode ;
20682089 }
20692090
20702091 boolean coerce () {
@@ -2081,6 +2102,11 @@ public NumberFieldType fieldType() {
20812102 return (NumberFieldType ) super .fieldType ();
20822103 }
20832104
2105+ @ Override
2106+ public String getOffsetFieldName () {
2107+ return offsetsFieldName ;
2108+ }
2109+
20842110 public NumberType type () {
20852111 return type ;
20862112 }
@@ -2109,7 +2135,17 @@ protected void parseCreateField(DocumentParserContext context) throws IOExceptio
21092135 }
21102136 if (value != null ) {
21112137 indexValue (context , value );
2138+ } else {
2139+ value = fieldType ().nullValue ;
2140+ }
2141+ if (offsetsFieldName != null && context .isImmediateParentAnArray () && context .canAddIgnoredField ()) {
2142+ if (value != null ) {
2143+ context .getOffSetContext ().recordOffset (offsetsFieldName , (Comparable <?>) value );
2144+ } else {
2145+ context .getOffSetContext ().recordNull (offsetsFieldName );
2146+ }
21122147 }
2148+
21132149 }
21142150
21152151 /**
@@ -2170,11 +2206,16 @@ protected void indexScriptValues(
21702206
21712207 @ Override
21722208 public FieldMapper .Builder getMergeBuilder () {
2173- return new Builder (leafName (), type , scriptCompiler , ignoreMalformedByDefault , coerceByDefault , indexCreatedVersion , indexMode )
2174- .dimension (dimension )
2175- .metric (metricType )
2176- .allowMultipleValues (allowMultipleValues )
2177- .init (this );
2209+ return new Builder (
2210+ leafName (),
2211+ type ,
2212+ scriptCompiler ,
2213+ ignoreMalformedByDefault ,
2214+ coerceByDefault ,
2215+ indexCreatedVersion ,
2216+ indexMode ,
2217+ indexSourceKeepMode
2218+ ).dimension (dimension ).metric (metricType ).allowMultipleValues (allowMultipleValues ).init (this );
21782219 }
21792220
21802221 @ Override
@@ -2186,10 +2227,23 @@ public void doValidate(MappingLookup lookup) {
21862227 }
21872228 }
21882229
2230+ private SourceLoader .SyntheticFieldLoader docValuesSyntheticFieldLoader () {
2231+ if (offsetsFieldName != null ) {
2232+ var layers = new ArrayList <CompositeSyntheticFieldLoader .Layer >();
2233+ layers .add (new SortedNumericWithOffsetsDocValuesSyntheticFieldLoaderLayer (fullPath (), offsetsFieldName , type ::writeValue ));
2234+ if (ignoreMalformed .value ()) {
2235+ layers .add (new CompositeSyntheticFieldLoader .MalformedValuesLayer (fullPath ()));
2236+ }
2237+ return new CompositeSyntheticFieldLoader (leafName (), fullPath (), layers );
2238+ } else {
2239+ return type .syntheticFieldLoader (fullPath (), leafName (), ignoreMalformed .value ());
2240+ }
2241+ }
2242+
21892243 @ Override
21902244 protected SyntheticSourceSupport syntheticSourceSupport () {
21912245 if (hasDocValues ) {
2192- return new SyntheticSourceSupport .Native (() -> type . syntheticFieldLoader ( fullPath (), leafName (), ignoreMalformed . value ()) );
2246+ return new SyntheticSourceSupport .Native (this :: docValuesSyntheticFieldLoader );
21932247 }
21942248
21952249 return super .syntheticSourceSupport ();
0 commit comments