|  | @@ -20,9 +20,7 @@
 | 
	
		
			
				|  |  |  package org.elasticsearch.index.mapper;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import org.apache.lucene.document.Field;
 | 
	
		
			
				|  |  | -import org.apache.lucene.document.FieldType;
 | 
	
		
			
				|  |  |  import org.apache.lucene.index.DocValues;
 | 
	
		
			
				|  |  | -import org.apache.lucene.index.IndexOptions;
 | 
	
		
			
				|  |  |  import org.apache.lucene.index.LeafReaderContext;
 | 
	
		
			
				|  |  |  import org.apache.lucene.index.NumericDocValues;
 | 
	
		
			
				|  |  |  import org.apache.lucene.index.SortedNumericDocValues;
 | 
	
	
		
			
				|  | @@ -34,13 +32,12 @@ import org.apache.lucene.search.TermQuery;
 | 
	
		
			
				|  |  |  import org.apache.lucene.util.BytesRef;
 | 
	
		
			
				|  |  |  import org.elasticsearch.common.Explicit;
 | 
	
		
			
				|  |  |  import org.elasticsearch.common.settings.Setting;
 | 
	
		
			
				|  |  | -import org.elasticsearch.common.xcontent.XContentBuilder;
 | 
	
		
			
				|  |  | +import org.elasticsearch.common.settings.Settings;
 | 
	
		
			
				|  |  |  import org.elasticsearch.common.xcontent.XContentParser;
 | 
	
		
			
				|  |  |  import org.elasticsearch.common.xcontent.XContentParser.Token;
 | 
	
		
			
				|  |  |  import org.elasticsearch.common.xcontent.support.XContentMapValues;
 | 
	
		
			
				|  |  |  import org.elasticsearch.index.fielddata.FieldData;
 | 
	
		
			
				|  |  |  import org.elasticsearch.index.fielddata.IndexFieldData;
 | 
	
		
			
				|  |  | -import org.elasticsearch.index.fielddata.IndexFieldDataCache;
 | 
	
		
			
				|  |  |  import org.elasticsearch.index.fielddata.IndexNumericFieldData;
 | 
	
		
			
				|  |  |  import org.elasticsearch.index.fielddata.LeafNumericFieldData;
 | 
	
		
			
				|  |  |  import org.elasticsearch.index.fielddata.NumericDoubleValues;
 | 
	
	
		
			
				|  | @@ -48,9 +45,7 @@ import org.elasticsearch.index.fielddata.ScriptDocValues;
 | 
	
		
			
				|  |  |  import org.elasticsearch.index.fielddata.SortedBinaryDocValues;
 | 
	
		
			
				|  |  |  import org.elasticsearch.index.fielddata.SortedNumericDoubleValues;
 | 
	
		
			
				|  |  |  import org.elasticsearch.index.fielddata.plain.SortedNumericIndexFieldData;
 | 
	
		
			
				|  |  | -import org.elasticsearch.index.mapper.NumberFieldMapper.Defaults;
 | 
	
		
			
				|  |  |  import org.elasticsearch.index.query.QueryShardContext;
 | 
	
		
			
				|  |  | -import org.elasticsearch.indices.breaker.CircuitBreakerService;
 | 
	
		
			
				|  |  |  import org.elasticsearch.search.DocValueFormat;
 | 
	
		
			
				|  |  |  import org.elasticsearch.search.aggregations.support.ValuesSourceType;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -59,124 +54,82 @@ import java.math.BigDecimal;
 | 
	
		
			
				|  |  |  import java.time.ZoneId;
 | 
	
		
			
				|  |  |  import java.util.ArrayList;
 | 
	
		
			
				|  |  |  import java.util.Collections;
 | 
	
		
			
				|  |  | -import java.util.Iterator;
 | 
	
		
			
				|  |  |  import java.util.List;
 | 
	
		
			
				|  |  |  import java.util.Map;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /** A {@link FieldMapper} for scaled floats. Values are internally multiplied
 | 
	
		
			
				|  |  |   *  by a scaling factor and rounded to the closest long. */
 | 
	
		
			
				|  |  | -public class ScaledFloatFieldMapper extends FieldMapper {
 | 
	
		
			
				|  |  | +public class ScaledFloatFieldMapper extends ParametrizedFieldMapper {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      public static final String CONTENT_TYPE = "scaled_float";
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      // use the same default as numbers
 | 
	
		
			
				|  |  |      private static final Setting<Boolean> COERCE_SETTING = NumberFieldMapper.COERCE_SETTING;
 | 
	
		
			
				|  |  | -    private static final FieldType FIELD_TYPE = new FieldType();
 | 
	
		
			
				|  |  | -    static {
 | 
	
		
			
				|  |  | -        FIELD_TYPE.setIndexOptions(IndexOptions.DOCS);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    private static ScaledFloatFieldMapper toType(FieldMapper in) {
 | 
	
		
			
				|  |  | +        return (ScaledFloatFieldMapper) in;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    public static class Builder extends FieldMapper.Builder<Builder> {
 | 
	
		
			
				|  |  | +    public static class Builder extends ParametrizedFieldMapper.Builder {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        private boolean scalingFactorSet = false;
 | 
	
		
			
				|  |  | -        private double scalingFactor;
 | 
	
		
			
				|  |  | -        private Boolean ignoreMalformed;
 | 
	
		
			
				|  |  | -        private Boolean coerce;
 | 
	
		
			
				|  |  | -        private Double nullValue;
 | 
	
		
			
				|  |  | +        private final Parameter<Boolean> indexed = Parameter.indexParam(m -> toType(m).indexed, true);
 | 
	
		
			
				|  |  | +        private final Parameter<Boolean> hasDocValues = Parameter.docValuesParam(m -> toType(m).hasDocValues, true);
 | 
	
		
			
				|  |  | +        private final Parameter<Boolean> stored = Parameter.storeParam(m -> toType(m).stored, false);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        public Builder(String name) {
 | 
	
		
			
				|  |  | -            super(name, FIELD_TYPE);
 | 
	
		
			
				|  |  | -            builder = this;
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | +        private final Parameter<Explicit<Boolean>> ignoreMalformed;
 | 
	
		
			
				|  |  | +        private final Parameter<Explicit<Boolean>> coerce;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        public Builder ignoreMalformed(boolean ignoreMalformed) {
 | 
	
		
			
				|  |  | -            this.ignoreMalformed = ignoreMalformed;
 | 
	
		
			
				|  |  | -            return builder;
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | +        private final Parameter<Double> scalingFactor = new Parameter<>("scaling_factor", false, () -> null,
 | 
	
		
			
				|  |  | +            (n, c, o) -> XContentMapValues.nodeDoubleValue(o), m -> toType(m).scalingFactor)
 | 
	
		
			
				|  |  | +            .setValidator(v -> {
 | 
	
		
			
				|  |  | +                if (v == null) {
 | 
	
		
			
				|  |  | +                    throw new IllegalArgumentException("Field [scaling_factor] is required");
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                if (Double.isFinite(v) == false || v <= 0) {
 | 
	
		
			
				|  |  | +                    throw new IllegalArgumentException("[scaling_factor] must be a positive number, got [" + v + "]");
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            });
 | 
	
		
			
				|  |  | +        private final Parameter<Double> nullValue = new Parameter<>("null_value", false, () -> null,
 | 
	
		
			
				|  |  | +            (n, c, o) -> XContentMapValues.nodeDoubleValue(o), m -> toType(m).nullValue);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        @Override
 | 
	
		
			
				|  |  | -        public Builder indexOptions(IndexOptions indexOptions) {
 | 
	
		
			
				|  |  | -            throw new MapperParsingException(
 | 
	
		
			
				|  |  | -                    "index_options not allowed in field [" + name + "] of type [" + CONTENT_TYPE + "]");
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | +        private final Parameter<Map<String, String>> meta = Parameter.metaParam();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        protected Explicit<Boolean> ignoreMalformed(BuilderContext context) {
 | 
	
		
			
				|  |  | -            if (ignoreMalformed != null) {
 | 
	
		
			
				|  |  | -                return new Explicit<>(ignoreMalformed, true);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            if (context.indexSettings() != null) {
 | 
	
		
			
				|  |  | -                return new Explicit<>(IGNORE_MALFORMED_SETTING.get(context.indexSettings()), false);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            return Defaults.IGNORE_MALFORMED;
 | 
	
		
			
				|  |  | +        public Builder(String name, Settings settings) {
 | 
	
		
			
				|  |  | +            this(name, IGNORE_MALFORMED_SETTING.get(settings), COERCE_SETTING.get(settings));
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        public Builder coerce(boolean coerce) {
 | 
	
		
			
				|  |  | -            this.coerce = coerce;
 | 
	
		
			
				|  |  | -            return builder;
 | 
	
		
			
				|  |  | +        public Builder(String name, boolean ignoreMalformedByDefault, boolean coerceByDefault) {
 | 
	
		
			
				|  |  | +            super(name);
 | 
	
		
			
				|  |  | +            this.ignoreMalformed
 | 
	
		
			
				|  |  | +                = Parameter.explicitBoolParam("ignore_malformed", true, m -> toType(m).ignoreMalformed, ignoreMalformedByDefault);
 | 
	
		
			
				|  |  | +            this.coerce
 | 
	
		
			
				|  |  | +                = Parameter.explicitBoolParam("coerce", true, m -> toType(m).coerce, coerceByDefault);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        public Builder scalingFactor(double scalingFactor) {
 | 
	
		
			
				|  |  | -            this.scalingFactor = scalingFactor;
 | 
	
		
			
				|  |  | -            scalingFactorSet = true;
 | 
	
		
			
				|  |  | +        Builder scalingFactor(double scalingFactor) {
 | 
	
		
			
				|  |  | +            this.scalingFactor.setValue(scalingFactor);
 | 
	
		
			
				|  |  |              return this;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        public Builder nullValue(Double nullValue) {
 | 
	
		
			
				|  |  | -            this.nullValue = nullValue;
 | 
	
		
			
				|  |  | +        Builder nullValue(double nullValue) {
 | 
	
		
			
				|  |  | +            this.nullValue.setValue(nullValue);
 | 
	
		
			
				|  |  |              return this;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        protected Explicit<Boolean> coerce(BuilderContext context) {
 | 
	
		
			
				|  |  | -            if (coerce != null) {
 | 
	
		
			
				|  |  | -                return new Explicit<>(coerce, true);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            if (context.indexSettings() != null) {
 | 
	
		
			
				|  |  | -                return new Explicit<>(COERCE_SETTING.get(context.indexSettings()), false);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            return Defaults.COERCE;
 | 
	
		
			
				|  |  | +        @Override
 | 
	
		
			
				|  |  | +        protected List<Parameter<?>> getParameters() {
 | 
	
		
			
				|  |  | +            return List.of(indexed, hasDocValues, stored, ignoreMalformed, meta, scalingFactor, coerce, nullValue);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          @Override
 | 
	
		
			
				|  |  |          public ScaledFloatFieldMapper build(BuilderContext context) {
 | 
	
		
			
				|  |  | -            if (scalingFactorSet == false) {
 | 
	
		
			
				|  |  | -                throw new IllegalArgumentException("Field [" + name + "] misses required parameter [scaling_factor]");
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            ScaledFloatFieldType type = new ScaledFloatFieldType(buildFullName(context), indexed, hasDocValues, meta, scalingFactor);
 | 
	
		
			
				|  |  | -            return new ScaledFloatFieldMapper(name, fieldType, type, ignoreMalformed(context),
 | 
	
		
			
				|  |  | -                    coerce(context), multiFieldsBuilder.build(this, context), copyTo, nullValue);
 | 
	
		
			
				|  |  | +            ScaledFloatFieldType type = new ScaledFloatFieldType(buildFullName(context), indexed.getValue(), hasDocValues.getValue(),
 | 
	
		
			
				|  |  | +                meta.getValue(), scalingFactor.getValue());
 | 
	
		
			
				|  |  | +            return new ScaledFloatFieldMapper(name, type, multiFieldsBuilder.build(this, context), copyTo.build(), this);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    public static class TypeParser implements Mapper.TypeParser {
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        @Override
 | 
	
		
			
				|  |  | -        public Mapper.Builder<?> parse(String name, Map<String, Object> node,
 | 
	
		
			
				|  |  | -                                         ParserContext parserContext) throws MapperParsingException {
 | 
	
		
			
				|  |  | -            Builder builder = new Builder(name);
 | 
	
		
			
				|  |  | -            TypeParsers.parseField(builder, name, node, parserContext);
 | 
	
		
			
				|  |  | -            for (Iterator<Map.Entry<String, Object>> iterator = node.entrySet().iterator(); iterator.hasNext();) {
 | 
	
		
			
				|  |  | -                Map.Entry<String, Object> entry = iterator.next();
 | 
	
		
			
				|  |  | -                String propName = entry.getKey();
 | 
	
		
			
				|  |  | -                Object propNode = entry.getValue();
 | 
	
		
			
				|  |  | -                if (propName.equals("null_value")) {
 | 
	
		
			
				|  |  | -                    if (propNode == null) {
 | 
	
		
			
				|  |  | -                        throw new MapperParsingException("Property [null_value] cannot be null.");
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                    builder.nullValue(ScaledFloatFieldMapper.parse(propNode));
 | 
	
		
			
				|  |  | -                    iterator.remove();
 | 
	
		
			
				|  |  | -                } else if (propName.equals("ignore_malformed")) {
 | 
	
		
			
				|  |  | -                    builder.ignoreMalformed(XContentMapValues.nodeBooleanValue(propNode, name + ".ignore_malformed"));
 | 
	
		
			
				|  |  | -                    iterator.remove();
 | 
	
		
			
				|  |  | -                } else if (propName.equals("coerce")) {
 | 
	
		
			
				|  |  | -                    builder.coerce(XContentMapValues.nodeBooleanValue(propNode, name + ".coerce"));
 | 
	
		
			
				|  |  | -                    iterator.remove();
 | 
	
		
			
				|  |  | -                } else if (propName.equals("scaling_factor")) {
 | 
	
		
			
				|  |  | -                    builder.scalingFactor(ScaledFloatFieldMapper.parse(propNode));
 | 
	
		
			
				|  |  | -                    iterator.remove();
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            return builder;
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | +    public static final TypeParser PARSER = new TypeParser((n, c) -> new Builder(n, c.getSettings()));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      public static final class ScaledFloatFieldType extends SimpleMappedFieldType {
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -264,19 +217,12 @@ public class ScaledFloatFieldMapper extends FieldMapper {
 | 
	
		
			
				|  |  |          @Override
 | 
	
		
			
				|  |  |          public IndexFieldData.Builder fielddataBuilder(String fullyQualifiedIndexName) {
 | 
	
		
			
				|  |  |              failIfNoDocValues();
 | 
	
		
			
				|  |  | -            return new IndexFieldData.Builder() {
 | 
	
		
			
				|  |  | -                @Override
 | 
	
		
			
				|  |  | -                public IndexFieldData<?> build(
 | 
	
		
			
				|  |  | -                    IndexFieldDataCache cache,
 | 
	
		
			
				|  |  | -                    CircuitBreakerService breakerService,
 | 
	
		
			
				|  |  | -                    MapperService mapperService
 | 
	
		
			
				|  |  | -                ) {
 | 
	
		
			
				|  |  | -                    final IndexNumericFieldData scaledValues = new SortedNumericIndexFieldData.Builder(
 | 
	
		
			
				|  |  | -                        name(),
 | 
	
		
			
				|  |  | -                        IndexNumericFieldData.NumericType.LONG
 | 
	
		
			
				|  |  | -                    ).build(cache, breakerService, mapperService);
 | 
	
		
			
				|  |  | -                    return new ScaledFloatIndexFieldData(scaledValues, scalingFactor);
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | +            return (cache, breakerService, mapperService) -> {
 | 
	
		
			
				|  |  | +                final IndexNumericFieldData scaledValues = new SortedNumericIndexFieldData.Builder(
 | 
	
		
			
				|  |  | +                    name(),
 | 
	
		
			
				|  |  | +                    IndexNumericFieldData.NumericType.LONG
 | 
	
		
			
				|  |  | +                ).build(cache, breakerService, mapperService);
 | 
	
		
			
				|  |  | +                return new ScaledFloatIndexFieldData(scaledValues, scalingFactor);
 | 
	
		
			
				|  |  |              };
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -315,30 +261,33 @@ public class ScaledFloatFieldMapper extends FieldMapper {
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    private Explicit<Boolean> ignoreMalformed;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    private Explicit<Boolean> coerce;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +    private final Explicit<Boolean> ignoreMalformed;
 | 
	
		
			
				|  |  | +    private final Explicit<Boolean> coerce;
 | 
	
		
			
				|  |  | +    private final boolean indexed;
 | 
	
		
			
				|  |  | +    private final boolean hasDocValues;
 | 
	
		
			
				|  |  | +    private final boolean stored;
 | 
	
		
			
				|  |  |      private final Double nullValue;
 | 
	
		
			
				|  |  |      private final double scalingFactor;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    private final boolean ignoreMalformedByDefault;
 | 
	
		
			
				|  |  | +    private final boolean coerceByDefault;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      private ScaledFloatFieldMapper(
 | 
	
		
			
				|  |  |              String simpleName,
 | 
	
		
			
				|  |  | -            FieldType fieldType,
 | 
	
		
			
				|  |  |              ScaledFloatFieldType mappedFieldType,
 | 
	
		
			
				|  |  | -            Explicit<Boolean> ignoreMalformed,
 | 
	
		
			
				|  |  | -            Explicit<Boolean> coerce,
 | 
	
		
			
				|  |  |              MultiFields multiFields,
 | 
	
		
			
				|  |  |              CopyTo copyTo,
 | 
	
		
			
				|  |  | -            Double nullValue) {
 | 
	
		
			
				|  |  | -        super(simpleName, fieldType, mappedFieldType, multiFields, copyTo);
 | 
	
		
			
				|  |  | -        this.scalingFactor = mappedFieldType.scalingFactor;
 | 
	
		
			
				|  |  | -        this.nullValue = nullValue;
 | 
	
		
			
				|  |  | -        if (Double.isFinite(scalingFactor) == false || scalingFactor <= 0) {
 | 
	
		
			
				|  |  | -            throw new IllegalArgumentException("[scaling_factor] must be a positive number, got [" + scalingFactor + "]");
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        this.ignoreMalformed = ignoreMalformed;
 | 
	
		
			
				|  |  | -        this.coerce = coerce;
 | 
	
		
			
				|  |  | +            Builder builder) {
 | 
	
		
			
				|  |  | +        super(simpleName, mappedFieldType, multiFields, copyTo);
 | 
	
		
			
				|  |  | +        this.indexed = builder.indexed.getValue();
 | 
	
		
			
				|  |  | +        this.hasDocValues = builder.hasDocValues.getValue();
 | 
	
		
			
				|  |  | +        this.stored = builder.stored.getValue();
 | 
	
		
			
				|  |  | +        this.scalingFactor = builder.scalingFactor.getValue();
 | 
	
		
			
				|  |  | +        this.nullValue = builder.nullValue.getValue();
 | 
	
		
			
				|  |  | +        this.ignoreMalformed = builder.ignoreMalformed.getValue();
 | 
	
		
			
				|  |  | +        this.coerce = builder.coerce.getValue();
 | 
	
		
			
				|  |  | +        this.ignoreMalformedByDefault = builder.ignoreMalformed.getDefaultValue().value();
 | 
	
		
			
				|  |  | +        this.coerceByDefault = builder.coerce.getDefaultValue().value();
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
	
		
			
				|  | @@ -351,6 +300,11 @@ public class ScaledFloatFieldMapper extends FieldMapper {
 | 
	
		
			
				|  |  |          return CONTENT_TYPE;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public ParametrizedFieldMapper.Builder getMergeBuilder() {
 | 
	
		
			
				|  |  | +        return new Builder(simpleName(), ignoreMalformedByDefault, coerceByDefault).init(this);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      protected ScaledFloatFieldMapper clone() {
 | 
	
		
			
				|  |  |          return (ScaledFloatFieldMapper) super.clone();
 | 
	
	
		
			
				|  | @@ -406,49 +360,15 @@ public class ScaledFloatFieldMapper extends FieldMapper {
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          long scaledValue = Math.round(doubleValue * scalingFactor);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        boolean indexed = fieldType().isSearchable();
 | 
	
		
			
				|  |  | -        boolean docValued = fieldType().hasDocValues();
 | 
	
		
			
				|  |  | -        boolean stored = fieldType.stored();
 | 
	
		
			
				|  |  | -        List<Field> fields = NumberFieldMapper.NumberType.LONG.createFields(fieldType().name(), scaledValue, indexed, docValued, stored);
 | 
	
		
			
				|  |  | +        List<Field> fields
 | 
	
		
			
				|  |  | +            = NumberFieldMapper.NumberType.LONG.createFields(fieldType().name(), scaledValue, indexed, hasDocValues, stored);
 | 
	
		
			
				|  |  |          context.doc().addAll(fields);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        if (docValued == false && (indexed || stored)) {
 | 
	
		
			
				|  |  | +        if (hasDocValues == false && (indexed || stored)) {
 | 
	
		
			
				|  |  |              createFieldNamesField(context);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    @Override
 | 
	
		
			
				|  |  | -    protected void mergeOptions(FieldMapper other, List<String> conflicts) {
 | 
	
		
			
				|  |  | -        ScaledFloatFieldMapper mergeWith = (ScaledFloatFieldMapper) other;
 | 
	
		
			
				|  |  | -        ScaledFloatFieldType ft = (ScaledFloatFieldType) other.fieldType();
 | 
	
		
			
				|  |  | -        if (fieldType().scalingFactor != ft.scalingFactor) {
 | 
	
		
			
				|  |  | -            conflicts.add("mapper [" + name() + "] has different [scaling_factor] values");
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        if (mergeWith.ignoreMalformed.explicit()) {
 | 
	
		
			
				|  |  | -            this.ignoreMalformed = mergeWith.ignoreMalformed;
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        if (mergeWith.coerce.explicit()) {
 | 
	
		
			
				|  |  | -            this.coerce = mergeWith.coerce;
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    @Override
 | 
	
		
			
				|  |  | -    protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
 | 
	
		
			
				|  |  | -        super.doXContentBody(builder, includeDefaults, params);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        builder.field("scaling_factor", scalingFactor);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        if (includeDefaults || ignoreMalformed.explicit()) {
 | 
	
		
			
				|  |  | -            builder.field("ignore_malformed", ignoreMalformed.value());
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        if (includeDefaults || coerce.explicit()) {
 | 
	
		
			
				|  |  | -            builder.field("coerce", coerce.value());
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        if (nullValue != null) {
 | 
	
		
			
				|  |  | -            builder.field("null_value", nullValue);
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |      static Double parse(Object value) {
 | 
	
		
			
				|  |  |          return objectToDouble(value);
 | 
	
		
			
				|  |  |      }
 |