Browse Source

Change default numeric precision_step

Change the default numeric precision_step to 16 for 64-bit types,
8 for 32-bit and 16-bit types. Disable precision_step for the 8-bit
byte type.

Closes #5905
Robert Muir 11 years ago
parent
commit
8568c18e6f
28 changed files with 271 additions and 96 deletions
  1. 11 1
      core-signatures.txt
  2. 5 4
      docs/reference/mapping/types/core-types.asciidoc
  3. 4 3
      docs/reference/mapping/types/geo-point-type.asciidoc
  4. 2 2
      docs/reference/mapping/types/ip-type.asciidoc
  5. 0 5
      src/main/java/org/elasticsearch/index/analysis/NumericDateAnalyzer.java
  6. 0 5
      src/main/java/org/elasticsearch/index/analysis/NumericDoubleAnalyzer.java
  7. 0 5
      src/main/java/org/elasticsearch/index/analysis/NumericFloatAnalyzer.java
  8. 0 5
      src/main/java/org/elasticsearch/index/analysis/NumericIntegerAnalyzer.java
  9. 0 5
      src/main/java/org/elasticsearch/index/analysis/NumericLongAnalyzer.java
  10. 3 3
      src/main/java/org/elasticsearch/index/mapper/core/ByteFieldMapper.java
  11. 3 3
      src/main/java/org/elasticsearch/index/mapper/core/DateFieldMapper.java
  12. 3 3
      src/main/java/org/elasticsearch/index/mapper/core/DoubleFieldMapper.java
  13. 3 3
      src/main/java/org/elasticsearch/index/mapper/core/FloatFieldMapper.java
  14. 3 3
      src/main/java/org/elasticsearch/index/mapper/core/IntegerFieldMapper.java
  15. 3 3
      src/main/java/org/elasticsearch/index/mapper/core/LongFieldMapper.java
  16. 2 2
      src/main/java/org/elasticsearch/index/mapper/core/Murmur3FieldMapper.java
  17. 19 10
      src/main/java/org/elasticsearch/index/mapper/core/NumberFieldMapper.java
  18. 4 3
      src/main/java/org/elasticsearch/index/mapper/core/ShortFieldMapper.java
  19. 2 2
      src/main/java/org/elasticsearch/index/mapper/core/TokenCountFieldMapper.java
  20. 3 3
      src/main/java/org/elasticsearch/index/mapper/internal/BoostFieldMapper.java
  21. 2 2
      src/main/java/org/elasticsearch/index/mapper/internal/SizeFieldMapper.java
  22. 2 2
      src/main/java/org/elasticsearch/index/mapper/internal/TTLFieldMapper.java
  23. 2 2
      src/main/java/org/elasticsearch/index/mapper/internal/TimestampFieldMapper.java
  24. 3 7
      src/main/java/org/elasticsearch/index/mapper/ip/IpFieldMapper.java
  25. 4 3
      src/main/java/org/elasticsearch/indices/ttl/IndicesTTLService.java
  26. 180 0
      src/test/java/org/elasticsearch/index/mapper/numeric/SimpleNumericTests.java
  27. 5 4
      src/test/java/org/elasticsearch/index/query/SimpleIndexQueryParserTests.java
  28. 3 3
      src/test/java/org/elasticsearch/index/query/span-multi-term-range-term.json

+ 11 - 1
core-signatures.txt

@@ -34,6 +34,16 @@ org.apache.lucene.index.IndexWriter#forceMergeDeletes(boolean) @ use Merges#forc
 @defaultMessage QueryWrapperFilter is cachable by default - use Queries#wrap instead
 org.apache.lucene.search.QueryWrapperFilter#<init>(org.apache.lucene.search.Query)
 
+@defaultMessage Pass the precision step from the mappings explicitly instead
+org.apache.lucene.search.NumericRangeQuery#newDoubleRange(java.lang.String,java.lang.Double,java.lang.Double,boolean,boolean)
+org.apache.lucene.search.NumericRangeQuery#newFloatRange(java.lang.String,java.lang.Float,java.lang.Float,boolean,boolean)
+org.apache.lucene.search.NumericRangeQuery#newIntRange(java.lang.String,java.lang.Integer,java.lang.Integer,boolean,boolean)
+org.apache.lucene.search.NumericRangeQuery#newLongRange(java.lang.String,java.lang.Long,java.lang.Long,boolean,boolean)
+org.apache.lucene.search.NumericRangeFilter#newDoubleRange(java.lang.String,java.lang.Double,java.lang.Double,boolean,boolean)
+org.apache.lucene.search.NumericRangeFilter#newFloatRange(java.lang.String,java.lang.Float,java.lang.Float,boolean,boolean)
+org.apache.lucene.search.NumericRangeFilter#newIntRange(java.lang.String,java.lang.Integer,java.lang.Integer,boolean,boolean)
+org.apache.lucene.search.NumericRangeFilter#newLongRange(java.lang.String,java.lang.Long,java.lang.Long,boolean,boolean)
+
 @defaultMessage Only use wait / notify when really needed try to use concurrency primitives, latches or callbacks instead. 
 java.lang.Object#wait()
 java.lang.Object#wait(long)
@@ -46,4 +56,4 @@ java.lang.Math#abs(int)
 java.lang.Math#abs(long)
 
 @defaultMessage Use Long.compare instead we are on Java7
-com.google.common.primitives.Longs#compare(long,long)
+com.google.common.primitives.Longs#compare(long,long)

+ 5 - 4
docs/reference/mapping/types/core-types.asciidoc

@@ -238,8 +238,9 @@ in `_source`, have `include_in_all` enabled, or `store` be set to
 |`doc_values` |Set to `true` to store field values in a column-stride fashion.
 Automatically set to `true` when the fielddata format is `doc_values`.
 
-|`precision_step` |The precision step (number of terms generated for
-each number value). Defaults to `4`.
+|`precision_step` |The precision step (influences the number of terms 
+generated for each number value). Defaults to `16` for `long`, `double`,
+`8` for `short`, `integer`, `float`, and `2147483647` for `byte`.
 
 |`boost` |The boost value. Defaults to `1.0`.
 
@@ -347,8 +348,8 @@ in `_source`, have `include_in_all` enabled, or `store` be set to
 |`doc_values` |Set to `true` to store field values in a column-stride fashion.
 Automatically set to `true` when the fielddata format is `doc_values`.
 
-|`precision_step` |The precision step (number of terms generated for
-each number value). Defaults to `4`.
+|`precision_step` |The precision step (influences the number of terms 
+generated for each number value). Defaults to `16`.
 
 |`boost` |The boost value. Defaults to `1.0`.
 

+ 4 - 3
docs/reference/mapping/types/geo-point-type.asciidoc

@@ -155,9 +155,10 @@ is `true`).
 
 |`normalize_lon` |Set to `true` to normalize longitude.
 
-|`precision_step` |The precision step (number of terms generated for
-each number value) for `.lat` and `.lon` fields if `lat_lon` is set to `true`.
-Defaults to `4`.
+|`precision_step` |The precision step (influences the number of terms 
+generated for each number value) for `.lat` and `.lon` fields 
+if `lat_lon` is set to `true`.
+Defaults to `16`.
 |=======================================================================
 
 [float]

+ 2 - 2
docs/reference/mapping/types/ip-type.asciidoc

@@ -21,8 +21,8 @@ and it can be retrieved from it).
 `store` should be set to `true`, since if it's not indexed and not
 stored, there is nothing to do with it.
 
-|`precision_step` |The precision step (number of terms generated for
-each number value). Defaults to `4`.
+|`precision_step` |The precision step (influences the number of terms 
+generated for each number value). Defaults to `16`.
 
 |`boost` |The boost value. Defaults to `1.0`.
 

+ 0 - 5
src/main/java/org/elasticsearch/index/analysis/NumericDateAnalyzer.java

@@ -19,7 +19,6 @@
 
 package org.elasticsearch.index.analysis;
 
-import org.apache.lucene.util.NumericUtils;
 import org.joda.time.format.DateTimeFormatter;
 
 import java.io.IOException;
@@ -34,10 +33,6 @@ public class NumericDateAnalyzer extends NumericAnalyzer<NumericDateTokenizer> {
 
     private final DateTimeFormatter dateTimeFormatter;
 
-    public NumericDateAnalyzer(DateTimeFormatter dateTimeFormatter) {
-        this(NumericUtils.PRECISION_STEP_DEFAULT, dateTimeFormatter);
-    }
-
     public NumericDateAnalyzer(int precisionStep, DateTimeFormatter dateTimeFormatter) {
         this.precisionStep = precisionStep;
         this.dateTimeFormatter = dateTimeFormatter;

+ 0 - 5
src/main/java/org/elasticsearch/index/analysis/NumericDoubleAnalyzer.java

@@ -20,7 +20,6 @@
 package org.elasticsearch.index.analysis;
 
 import com.carrotsearch.hppc.IntObjectOpenHashMap;
-import org.apache.lucene.util.NumericUtils;
 
 import java.io.IOException;
 import java.io.Reader;
@@ -50,10 +49,6 @@ public class NumericDoubleAnalyzer extends NumericAnalyzer<NumericDoubleTokenize
 
     private final int precisionStep;
 
-    public NumericDoubleAnalyzer() {
-        this(NumericUtils.PRECISION_STEP_DEFAULT);
-    }
-
     public NumericDoubleAnalyzer(int precisionStep) {
         this.precisionStep = precisionStep;
     }

+ 0 - 5
src/main/java/org/elasticsearch/index/analysis/NumericFloatAnalyzer.java

@@ -20,7 +20,6 @@
 package org.elasticsearch.index.analysis;
 
 import com.carrotsearch.hppc.IntObjectOpenHashMap;
-import org.apache.lucene.util.NumericUtils;
 
 import java.io.IOException;
 import java.io.Reader;
@@ -50,10 +49,6 @@ public class NumericFloatAnalyzer extends NumericAnalyzer<NumericFloatTokenizer>
 
     private final int precisionStep;
 
-    public NumericFloatAnalyzer() {
-        this(NumericUtils.PRECISION_STEP_DEFAULT);
-    }
-
     public NumericFloatAnalyzer(int precisionStep) {
         this.precisionStep = precisionStep;
     }

+ 0 - 5
src/main/java/org/elasticsearch/index/analysis/NumericIntegerAnalyzer.java

@@ -20,7 +20,6 @@
 package org.elasticsearch.index.analysis;
 
 import com.carrotsearch.hppc.IntObjectOpenHashMap;
-import org.apache.lucene.util.NumericUtils;
 
 import java.io.IOException;
 import java.io.Reader;
@@ -50,10 +49,6 @@ public class NumericIntegerAnalyzer extends NumericAnalyzer<NumericIntegerTokeni
 
     private final int precisionStep;
 
-    public NumericIntegerAnalyzer() {
-        this(NumericUtils.PRECISION_STEP_DEFAULT);
-    }
-
     public NumericIntegerAnalyzer(int precisionStep) {
         this.precisionStep = precisionStep;
     }

+ 0 - 5
src/main/java/org/elasticsearch/index/analysis/NumericLongAnalyzer.java

@@ -20,7 +20,6 @@
 package org.elasticsearch.index.analysis;
 
 import com.carrotsearch.hppc.IntObjectOpenHashMap;
-import org.apache.lucene.util.NumericUtils;
 
 import java.io.IOException;
 import java.io.Reader;
@@ -50,10 +49,6 @@ public class NumericLongAnalyzer extends NumericAnalyzer<NumericLongTokenizer> {
 
     private final int precisionStep;
 
-    public NumericLongAnalyzer() {
-        this(NumericUtils.PRECISION_STEP_DEFAULT);
-    }
-
     public NumericLongAnalyzer(int precisionStep) {
         this.precisionStep = precisionStep;
     }

+ 3 - 3
src/main/java/org/elasticsearch/index/mapper/core/ByteFieldMapper.java

@@ -78,7 +78,7 @@ public class ByteFieldMapper extends NumberFieldMapper<Byte> {
         protected Byte nullValue = Defaults.NULL_VALUE;
 
         public Builder(String name) {
-            super(name, new FieldType(Defaults.FIELD_TYPE));
+            super(name, new FieldType(Defaults.FIELD_TYPE), Defaults.PRECISION_STEP_8_BIT);
             builder = this;
         }
 
@@ -91,7 +91,7 @@ public class ByteFieldMapper extends NumberFieldMapper<Byte> {
         public ByteFieldMapper build(BuilderContext context) {
             fieldType.setOmitNorms(fieldType.omitNorms() && boost == 1.0f);
             ByteFieldMapper fieldMapper = new ByteFieldMapper(buildNames(context),
-                    precisionStep, boost, fieldType, docValues, nullValue, ignoreMalformed(context),
+                    fieldType.numericPrecisionStep(), boost, fieldType, docValues, nullValue, ignoreMalformed(context),
                     coerce(context), postingsProvider, docValuesProvider, similarity, normsLoading, 
                     fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
             fieldMapper.includeInAll(includeInAll);
@@ -346,7 +346,7 @@ public class ByteFieldMapper extends NumberFieldMapper<Byte> {
     protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
         super.doXContentBody(builder, includeDefaults, params);
 
-        if (includeDefaults || precisionStep != Defaults.PRECISION_STEP) {
+        if (includeDefaults || precisionStep != Defaults.PRECISION_STEP_8_BIT) {
             builder.field("precision_step", precisionStep);
         }
         if (includeDefaults || nullValue != null) {

+ 3 - 3
src/main/java/org/elasticsearch/index/mapper/core/DateFieldMapper.java

@@ -97,7 +97,7 @@ public class DateFieldMapper extends NumberFieldMapper<Long> {
         private Locale locale;
 
         public Builder(String name) {
-            super(name, new FieldType(Defaults.FIELD_TYPE));
+            super(name, new FieldType(Defaults.FIELD_TYPE), Defaults.PRECISION_STEP_64_BIT);
             builder = this;
             // do *NOT* rely on the default locale
             locale = Locale.ROOT;
@@ -130,7 +130,7 @@ public class DateFieldMapper extends NumberFieldMapper<Long> {
                 dateTimeFormatter = new FormatDateTimeFormatter(dateTimeFormatter.format(), dateTimeFormatter.parser(), dateTimeFormatter.printer(), locale);
             }
             DateFieldMapper fieldMapper = new DateFieldMapper(buildNames(context), dateTimeFormatter,
-                    precisionStep, boost, fieldType, docValues, nullValue, timeUnit, roundCeil, ignoreMalformed(context), coerce(context),
+                    fieldType.numericPrecisionStep(), boost, fieldType, docValues, nullValue, timeUnit, roundCeil, ignoreMalformed(context), coerce(context),
                     postingsProvider, docValuesProvider, similarity, normsLoading, fieldDataSettings, context.indexSettings(),
                     multiFieldsBuilder.build(this, context), copyTo);
             fieldMapper.includeInAll(includeInAll);
@@ -523,7 +523,7 @@ public class DateFieldMapper extends NumberFieldMapper<Long> {
     protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
         super.doXContentBody(builder, includeDefaults, params);
 
-        if (includeDefaults || precisionStep != Defaults.PRECISION_STEP) {
+        if (includeDefaults || precisionStep != Defaults.PRECISION_STEP_64_BIT) {
             builder.field("precision_step", precisionStep);
         }
         builder.field("format", dateTimeFormatter.format());

+ 3 - 3
src/main/java/org/elasticsearch/index/mapper/core/DoubleFieldMapper.java

@@ -82,7 +82,7 @@ public class DoubleFieldMapper extends NumberFieldMapper<Double> {
         protected Double nullValue = Defaults.NULL_VALUE;
 
         public Builder(String name) {
-            super(name, new FieldType(Defaults.FIELD_TYPE));
+            super(name, new FieldType(Defaults.FIELD_TYPE), Defaults.PRECISION_STEP_64_BIT);
             builder = this;
         }
 
@@ -95,7 +95,7 @@ public class DoubleFieldMapper extends NumberFieldMapper<Double> {
         public DoubleFieldMapper build(BuilderContext context) {
             fieldType.setOmitNorms(fieldType.omitNorms() && boost == 1.0f);
             DoubleFieldMapper fieldMapper = new DoubleFieldMapper(buildNames(context),
-                    precisionStep, boost, fieldType, docValues, nullValue, ignoreMalformed(context), coerce(context), postingsProvider, 
+                    fieldType.numericPrecisionStep(), boost, fieldType, docValues, nullValue, ignoreMalformed(context), coerce(context), postingsProvider, 
                     docValuesProvider, similarity, normsLoading, fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
             fieldMapper.includeInAll(includeInAll);
             return fieldMapper;
@@ -348,7 +348,7 @@ public class DoubleFieldMapper extends NumberFieldMapper<Double> {
     protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
         super.doXContentBody(builder, includeDefaults, params);
 
-        if (includeDefaults || precisionStep != Defaults.PRECISION_STEP) {
+        if (includeDefaults || precisionStep != Defaults.PRECISION_STEP_64_BIT) {
             builder.field("precision_step", precisionStep);
         }
         if (includeDefaults || nullValue != null) {

+ 3 - 3
src/main/java/org/elasticsearch/index/mapper/core/FloatFieldMapper.java

@@ -83,7 +83,7 @@ public class FloatFieldMapper extends NumberFieldMapper<Float> {
         protected Float nullValue = Defaults.NULL_VALUE;
 
         public Builder(String name) {
-            super(name, new FieldType(Defaults.FIELD_TYPE));
+            super(name, new FieldType(Defaults.FIELD_TYPE), Defaults.PRECISION_STEP_32_BIT);
             builder = this;
         }
 
@@ -96,7 +96,7 @@ public class FloatFieldMapper extends NumberFieldMapper<Float> {
         public FloatFieldMapper build(BuilderContext context) {
             fieldType.setOmitNorms(fieldType.omitNorms() && boost == 1.0f);
             FloatFieldMapper fieldMapper = new FloatFieldMapper(buildNames(context),
-                    precisionStep, boost, fieldType, docValues, nullValue, ignoreMalformed(context), coerce(context), postingsProvider, 
+                    fieldType.numericPrecisionStep(), boost, fieldType, docValues, nullValue, ignoreMalformed(context), coerce(context), postingsProvider, 
                     docValuesProvider, similarity, normsLoading, fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
             fieldMapper.includeInAll(includeInAll);
             return fieldMapper;
@@ -354,7 +354,7 @@ public class FloatFieldMapper extends NumberFieldMapper<Float> {
     protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
         super.doXContentBody(builder, includeDefaults, params);
 
-        if (includeDefaults || precisionStep != Defaults.PRECISION_STEP) {
+        if (includeDefaults || precisionStep != Defaults.PRECISION_STEP_32_BIT) {
             builder.field("precision_step", precisionStep);
         }
         if (includeDefaults || nullValue != null) {

+ 3 - 3
src/main/java/org/elasticsearch/index/mapper/core/IntegerFieldMapper.java

@@ -79,7 +79,7 @@ public class IntegerFieldMapper extends NumberFieldMapper<Integer> {
         protected Integer nullValue = Defaults.NULL_VALUE;
 
         public Builder(String name) {
-            super(name, new FieldType(Defaults.FIELD_TYPE));
+            super(name, new FieldType(Defaults.FIELD_TYPE), Defaults.PRECISION_STEP_32_BIT);
             builder = this;
         }
 
@@ -91,7 +91,7 @@ public class IntegerFieldMapper extends NumberFieldMapper<Integer> {
         @Override
         public IntegerFieldMapper build(BuilderContext context) {
             fieldType.setOmitNorms(fieldType.omitNorms() && boost == 1.0f);
-            IntegerFieldMapper fieldMapper = new IntegerFieldMapper(buildNames(context), precisionStep, boost, fieldType, docValues,
+            IntegerFieldMapper fieldMapper = new IntegerFieldMapper(buildNames(context), fieldType.numericPrecisionStep(), boost, fieldType, docValues,
                     nullValue, ignoreMalformed(context), coerce(context), postingsProvider, docValuesProvider, similarity, normsLoading, fieldDataSettings, 
                     context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
             fieldMapper.includeInAll(includeInAll);
@@ -349,7 +349,7 @@ public class IntegerFieldMapper extends NumberFieldMapper<Integer> {
     protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
         super.doXContentBody(builder, includeDefaults, params);
 
-        if (includeDefaults || precisionStep != Defaults.PRECISION_STEP) {
+        if (includeDefaults || precisionStep != Defaults.PRECISION_STEP_32_BIT) {
             builder.field("precision_step", precisionStep);
         }
         if (includeDefaults || nullValue != null) {

+ 3 - 3
src/main/java/org/elasticsearch/index/mapper/core/LongFieldMapper.java

@@ -79,7 +79,7 @@ public class LongFieldMapper extends NumberFieldMapper<Long> {
         protected Long nullValue = Defaults.NULL_VALUE;
 
         public Builder(String name) {
-            super(name, new FieldType(Defaults.FIELD_TYPE));
+            super(name, new FieldType(Defaults.FIELD_TYPE), Defaults.PRECISION_STEP_64_BIT);
             builder = this;
         }
 
@@ -91,7 +91,7 @@ public class LongFieldMapper extends NumberFieldMapper<Long> {
         @Override
         public LongFieldMapper build(BuilderContext context) {
             fieldType.setOmitNorms(fieldType.omitNorms() && boost == 1.0f);
-            LongFieldMapper fieldMapper = new LongFieldMapper(buildNames(context), precisionStep, boost, fieldType, docValues, nullValue,
+            LongFieldMapper fieldMapper = new LongFieldMapper(buildNames(context), fieldType.numericPrecisionStep(), boost, fieldType, docValues, nullValue,
                     ignoreMalformed(context), coerce(context), postingsProvider, docValuesProvider, similarity, normsLoading, 
                     fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
             fieldMapper.includeInAll(includeInAll);
@@ -331,7 +331,7 @@ public class LongFieldMapper extends NumberFieldMapper<Long> {
     protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
         super.doXContentBody(builder, includeDefaults, params);
 
-        if (includeDefaults || precisionStep != Defaults.PRECISION_STEP) {
+        if (includeDefaults || precisionStep != Defaults.PRECISION_STEP_64_BIT) {
             builder.field("precision_step", precisionStep);
         }
         if (includeDefaults || nullValue != null) {

+ 2 - 2
src/main/java/org/elasticsearch/index/mapper/core/Murmur3FieldMapper.java

@@ -50,7 +50,7 @@ public class Murmur3FieldMapper extends LongFieldMapper {
     public static class Builder extends NumberFieldMapper.Builder<Builder, Murmur3FieldMapper> {
 
         public Builder(String name) {
-            super(name, new FieldType(Defaults.FIELD_TYPE));
+            super(name, new FieldType(Defaults.FIELD_TYPE), Integer.MAX_VALUE);
             builder = this;
             builder.precisionStep(Integer.MAX_VALUE);
         }
@@ -58,7 +58,7 @@ public class Murmur3FieldMapper extends LongFieldMapper {
         @Override
         public Murmur3FieldMapper build(BuilderContext context) {
             fieldType.setOmitNorms(fieldType.omitNorms() && boost == 1.0f);
-            Murmur3FieldMapper fieldMapper = new Murmur3FieldMapper(buildNames(context), precisionStep, boost, fieldType, docValues, ~0L,
+            Murmur3FieldMapper fieldMapper = new Murmur3FieldMapper(buildNames(context), fieldType.numericPrecisionStep(), boost, fieldType, docValues, ~0L,
                     ignoreMalformed(context), coerce(context), postingsProvider, docValuesProvider, similarity, normsLoading,
                     fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
             fieldMapper.includeInAll(includeInAll);

+ 19 - 10
src/main/java/org/elasticsearch/index/mapper/core/NumberFieldMapper.java

@@ -35,7 +35,6 @@ import org.apache.lucene.search.Filter;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.store.ByteArrayDataOutput;
 import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.NumericUtils;
 import org.elasticsearch.common.Explicit;
 import org.elasticsearch.common.Nullable;
 import org.elasticsearch.common.settings.Settings;
@@ -64,7 +63,11 @@ import java.util.List;
 public abstract class NumberFieldMapper<T extends Number> extends AbstractFieldMapper<T> implements AllFieldMapper.IncludeInAll {
 
     public static class Defaults extends AbstractFieldMapper.Defaults {
-        public static final int PRECISION_STEP = NumericUtils.PRECISION_STEP_DEFAULT;
+        
+        public static final int PRECISION_STEP_8_BIT  = Integer.MAX_VALUE; // 1tpv: 256 terms at most, not useful
+        public static final int PRECISION_STEP_16_BIT = 8;                 // 2tpv
+        public static final int PRECISION_STEP_32_BIT = 8;                 // 4tpv
+        public static final int PRECISION_STEP_64_BIT = 16;                // 4tpv
 
         public static final FieldType FIELD_TYPE = new FieldType(AbstractFieldMapper.Defaults.FIELD_TYPE);
 
@@ -82,18 +85,17 @@ public abstract class NumberFieldMapper<T extends Number> extends AbstractFieldM
 
     public abstract static class Builder<T extends Builder, Y extends NumberFieldMapper> extends AbstractFieldMapper.Builder<T, Y> {
 
-        protected int precisionStep = Defaults.PRECISION_STEP;
-
         private Boolean ignoreMalformed;
 
         private Boolean coerce;
         
-        public Builder(String name, FieldType fieldType) {
+        public Builder(String name, FieldType fieldType, int defaultPrecisionStep) {
             super(name, fieldType);
+            fieldType.setNumericPrecisionStep(defaultPrecisionStep);
         }
 
         public T precisionStep(int precisionStep) {
-            this.precisionStep = precisionStep;
+            fieldType.setNumericPrecisionStep(precisionStep);
             return builder;
         }
 
@@ -157,6 +159,13 @@ public abstract class NumberFieldMapper<T extends Number> extends AbstractFieldM
             return new NumericTokenStream(8);
         }
     };
+    
+    private static ThreadLocal<NumericTokenStream> tokenStream16 = new ThreadLocal<NumericTokenStream>() {
+        @Override
+        protected NumericTokenStream initialValue() {
+            return new NumericTokenStream(16);
+        }
+    };
 
     private static ThreadLocal<NumericTokenStream> tokenStreamMax = new ThreadLocal<NumericTokenStream>() {
         @Override
@@ -369,11 +378,11 @@ public abstract class NumberFieldMapper<T extends Number> extends AbstractFieldM
     protected NumericTokenStream popCachedStream() {
         if (precisionStep == 4) {
             return tokenStream4.get();
-        }
-        if (precisionStep == 8) {
+        } else if (precisionStep == 8) {
             return tokenStream8.get();
-        }
-        if (precisionStep == Integer.MAX_VALUE) {
+        } else if (precisionStep == 16) {
+            return tokenStream16.get();
+        } else if (precisionStep == Integer.MAX_VALUE) {
             return tokenStreamMax.get();
         }
         return tokenStream.get();

+ 4 - 3
src/main/java/org/elasticsearch/index/mapper/core/ShortFieldMapper.java

@@ -64,6 +64,7 @@ import static org.elasticsearch.index.mapper.core.TypeParsers.parseNumberField;
 public class ShortFieldMapper extends NumberFieldMapper<Short> {
 
     public static final String CONTENT_TYPE = "short";
+    public static final int DEFAULT_PRECISION_STEP = 8;
 
     public static class Defaults extends NumberFieldMapper.Defaults {
         public static final FieldType FIELD_TYPE = new FieldType(NumberFieldMapper.Defaults.FIELD_TYPE);
@@ -80,7 +81,7 @@ public class ShortFieldMapper extends NumberFieldMapper<Short> {
         protected Short nullValue = Defaults.NULL_VALUE;
 
         public Builder(String name) {
-            super(name, new FieldType(Defaults.FIELD_TYPE));
+            super(name, new FieldType(Defaults.FIELD_TYPE), DEFAULT_PRECISION_STEP);
             builder = this;
         }
 
@@ -92,7 +93,7 @@ public class ShortFieldMapper extends NumberFieldMapper<Short> {
         @Override
         public ShortFieldMapper build(BuilderContext context) {
             fieldType.setOmitNorms(fieldType.omitNorms() && boost == 1.0f);
-            ShortFieldMapper fieldMapper = new ShortFieldMapper(buildNames(context), precisionStep, boost, fieldType, docValues, nullValue,
+            ShortFieldMapper fieldMapper = new ShortFieldMapper(buildNames(context), fieldType.numericPrecisionStep(), boost, fieldType, docValues, nullValue,
                     ignoreMalformed(context), coerce(context),postingsProvider, docValuesProvider, similarity, normsLoading, fieldDataSettings, 
                     context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
             fieldMapper.includeInAll(includeInAll);
@@ -346,7 +347,7 @@ public class ShortFieldMapper extends NumberFieldMapper<Short> {
     protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
         super.doXContentBody(builder, includeDefaults, params);
 
-        if (includeDefaults || precisionStep != Defaults.PRECISION_STEP) {
+        if (includeDefaults || precisionStep != DEFAULT_PRECISION_STEP) {
             builder.field("precision_step", precisionStep);
         }
         if (includeDefaults || nullValue != null) {

+ 2 - 2
src/main/java/org/elasticsearch/index/mapper/core/TokenCountFieldMapper.java

@@ -57,7 +57,7 @@ public class TokenCountFieldMapper extends IntegerFieldMapper {
         private NamedAnalyzer analyzer;
 
         public Builder(String name) {
-            super(name, new FieldType(Defaults.FIELD_TYPE));
+            super(name, new FieldType(Defaults.FIELD_TYPE), Defaults.PRECISION_STEP_32_BIT);
             builder = this;
         }
 
@@ -78,7 +78,7 @@ public class TokenCountFieldMapper extends IntegerFieldMapper {
         @Override
         public TokenCountFieldMapper build(BuilderContext context) {
             fieldType.setOmitNorms(fieldType.omitNorms() && boost == 1.0f);
-            TokenCountFieldMapper fieldMapper = new TokenCountFieldMapper(buildNames(context), precisionStep, boost, fieldType, docValues, nullValue,
+            TokenCountFieldMapper fieldMapper = new TokenCountFieldMapper(buildNames(context), fieldType.numericPrecisionStep(), boost, fieldType, docValues, nullValue,
                     ignoreMalformed(context), coerce(context), postingsProvider, docValuesProvider, similarity, normsLoading, fieldDataSettings, context.indexSettings(),
                     analyzer, multiFieldsBuilder.build(this, context), copyTo);
             fieldMapper.includeInAll(includeInAll);

+ 3 - 3
src/main/java/org/elasticsearch/index/mapper/internal/BoostFieldMapper.java

@@ -79,7 +79,7 @@ public class BoostFieldMapper extends NumberFieldMapper<Float> implements Intern
         protected Float nullValue = Defaults.NULL_VALUE;
 
         public Builder(String name) {
-            super(name, new FieldType(Defaults.FIELD_TYPE));
+            super(name, new FieldType(Defaults.FIELD_TYPE), Defaults.PRECISION_STEP_32_BIT);
             builder = this;
         }
 
@@ -91,7 +91,7 @@ public class BoostFieldMapper extends NumberFieldMapper<Float> implements Intern
         @Override
         public BoostFieldMapper build(BuilderContext context) {
             return new BoostFieldMapper(name, buildIndexName(context),
-                    precisionStep, boost, fieldType, docValues, nullValue, postingsProvider, docValuesProvider, fieldDataSettings, context.indexSettings());
+                    fieldType.numericPrecisionStep(), boost, fieldType, docValues, nullValue, postingsProvider, docValuesProvider, fieldDataSettings, context.indexSettings());
         }
     }
 
@@ -119,7 +119,7 @@ public class BoostFieldMapper extends NumberFieldMapper<Float> implements Intern
     }
 
     protected BoostFieldMapper(String name, String indexName) {
-        this(name, indexName, Defaults.PRECISION_STEP, Defaults.BOOST, new FieldType(Defaults.FIELD_TYPE), null,
+        this(name, indexName, Defaults.PRECISION_STEP_32_BIT, Defaults.BOOST, new FieldType(Defaults.FIELD_TYPE), null,
                 Defaults.NULL_VALUE, null, null, null, ImmutableSettings.EMPTY);
     }
 

+ 2 - 2
src/main/java/org/elasticsearch/index/mapper/internal/SizeFieldMapper.java

@@ -61,7 +61,7 @@ public class SizeFieldMapper extends IntegerFieldMapper implements RootMapper {
         protected EnabledAttributeMapper enabledState = EnabledAttributeMapper.UNSET_DISABLED;
 
         public Builder() {
-            super(Defaults.NAME, new FieldType(Defaults.SIZE_FIELD_TYPE));
+            super(Defaults.NAME, new FieldType(Defaults.SIZE_FIELD_TYPE), Defaults.PRECISION_STEP_32_BIT);
             builder = this;
         }
 
@@ -101,7 +101,7 @@ public class SizeFieldMapper extends IntegerFieldMapper implements RootMapper {
 
     public SizeFieldMapper(EnabledAttributeMapper enabled, FieldType fieldType, PostingsFormatProvider postingsProvider,
                            DocValuesFormatProvider docValuesProvider, @Nullable Settings fieldDataSettings, Settings indexSettings) {
-        super(new Names(Defaults.NAME), Defaults.PRECISION_STEP, Defaults.BOOST, fieldType, null, Defaults.NULL_VALUE,
+        super(new Names(Defaults.NAME), Defaults.PRECISION_STEP_32_BIT, Defaults.BOOST, fieldType, null, Defaults.NULL_VALUE,
                 Defaults.IGNORE_MALFORMED,  Defaults.COERCE, postingsProvider, docValuesProvider, null, null, fieldDataSettings, 
                 indexSettings, MultiFields.empty(), null);
         this.enabledState = enabled;

+ 2 - 2
src/main/java/org/elasticsearch/index/mapper/internal/TTLFieldMapper.java

@@ -74,7 +74,7 @@ public class TTLFieldMapper extends LongFieldMapper implements InternalMapper, R
         private long defaultTTL = Defaults.DEFAULT;
 
         public Builder() {
-            super(Defaults.NAME, new FieldType(Defaults.TTL_FIELD_TYPE));
+            super(Defaults.NAME, new FieldType(Defaults.TTL_FIELD_TYPE), Defaults.PRECISION_STEP_64_BIT);
         }
 
         public Builder enabled(EnabledAttributeMapper enabled) {
@@ -125,7 +125,7 @@ public class TTLFieldMapper extends LongFieldMapper implements InternalMapper, R
     protected TTLFieldMapper(FieldType fieldType, EnabledAttributeMapper enabled, long defaultTTL, Explicit<Boolean> ignoreMalformed,
                 Explicit<Boolean> coerce, PostingsFormatProvider postingsProvider, DocValuesFormatProvider docValuesProvider,
                 @Nullable Settings fieldDataSettings, Settings indexSettings) {
-        super(new Names(Defaults.NAME, Defaults.NAME, Defaults.NAME, Defaults.NAME), Defaults.PRECISION_STEP,
+        super(new Names(Defaults.NAME, Defaults.NAME, Defaults.NAME, Defaults.NAME), Defaults.PRECISION_STEP_64_BIT,
                 Defaults.BOOST, fieldType, null, Defaults.NULL_VALUE, ignoreMalformed, coerce,
                 postingsProvider, docValuesProvider, null, null, fieldDataSettings, indexSettings, MultiFields.empty(), null);
         this.enabledState = enabled;

+ 2 - 2
src/main/java/org/elasticsearch/index/mapper/internal/TimestampFieldMapper.java

@@ -79,7 +79,7 @@ public class TimestampFieldMapper extends DateFieldMapper implements InternalMap
         private FormatDateTimeFormatter dateTimeFormatter = Defaults.DATE_TIME_FORMATTER;
 
         public Builder() {
-            super(Defaults.NAME, new FieldType(Defaults.FIELD_TYPE));
+            super(Defaults.NAME, new FieldType(Defaults.FIELD_TYPE), Defaults.PRECISION_STEP_64_BIT);
         }
 
         public Builder enabled(EnabledAttributeMapper enabledState) {
@@ -146,7 +146,7 @@ public class TimestampFieldMapper extends DateFieldMapper implements InternalMap
                                    DocValuesFormatProvider docValuesProvider, Loading normsLoading,
                                    @Nullable Settings fieldDataSettings, Settings indexSettings) {
         super(new Names(Defaults.NAME, Defaults.NAME, Defaults.NAME, Defaults.NAME), dateTimeFormatter,
-                Defaults.PRECISION_STEP, Defaults.BOOST, fieldType, docValues,
+                Defaults.PRECISION_STEP_64_BIT, Defaults.BOOST, fieldType, docValues,
                 Defaults.NULL_VALUE, TimeUnit.MILLISECONDS /*always milliseconds*/,
                 roundCeil, ignoreMalformed, coerce, postingsProvider, docValuesProvider, null, normsLoading, fieldDataSettings, 
                 indexSettings, MultiFields.empty(), null);

+ 3 - 7
src/main/java/org/elasticsearch/index/mapper/ip/IpFieldMapper.java

@@ -109,7 +109,7 @@ public class IpFieldMapper extends NumberFieldMapper<Long> {
         protected String nullValue = Defaults.NULL_VALUE;
 
         public Builder(String name) {
-            super(name, new FieldType(Defaults.FIELD_TYPE));
+            super(name, new FieldType(Defaults.FIELD_TYPE), Defaults.PRECISION_STEP_64_BIT);
             builder = this;
         }
 
@@ -122,7 +122,7 @@ public class IpFieldMapper extends NumberFieldMapper<Long> {
         public IpFieldMapper build(BuilderContext context) {
             fieldType.setOmitNorms(fieldType.omitNorms() && boost == 1.0f);
             IpFieldMapper fieldMapper = new IpFieldMapper(buildNames(context),
-                    precisionStep, boost, fieldType, docValues, nullValue, ignoreMalformed(context), coerce(context),
+                    fieldType.numericPrecisionStep(), boost, fieldType, docValues, nullValue, ignoreMalformed(context), coerce(context),
                     postingsProvider, docValuesProvider, similarity,
                     normsLoading, fieldDataSettings, context.indexSettings(), multiFieldsBuilder.build(this, context), copyTo);
             fieldMapper.includeInAll(includeInAll);
@@ -323,7 +323,7 @@ public class IpFieldMapper extends NumberFieldMapper<Long> {
     protected void doXContentBody(XContentBuilder builder, boolean includeDefaults, Params params) throws IOException {
         super.doXContentBody(builder, includeDefaults, params);
 
-        if (includeDefaults || precisionStep != Defaults.PRECISION_STEP) {
+        if (includeDefaults || precisionStep != Defaults.PRECISION_STEP_64_BIT) {
             builder.field("precision_step", precisionStep);
         }
         if (includeDefaults || nullValue != null) {
@@ -341,10 +341,6 @@ public class IpFieldMapper extends NumberFieldMapper<Long> {
 
         private final int precisionStep;
 
-        public NumericIpAnalyzer() {
-            this(NumericUtils.PRECISION_STEP_DEFAULT);
-        }
-
         public NumericIpAnalyzer(int precisionStep) {
             this.precisionStep = precisionStep;
         }

+ 4 - 3
src/main/java/org/elasticsearch/indices/ttl/IndicesTTLService.java

@@ -22,12 +22,13 @@ package org.elasticsearch.indices.ttl;
 import org.apache.lucene.index.AtomicReaderContext;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.search.Collector;
-import org.apache.lucene.search.NumericRangeQuery;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.Scorer;
 import org.elasticsearch.ElasticsearchException;
 import org.elasticsearch.action.ActionListener;
-import org.elasticsearch.action.bulk.*;
+import org.elasticsearch.action.bulk.BulkRequest;
+import org.elasticsearch.action.bulk.BulkResponse;
+import org.elasticsearch.action.bulk.TransportBulkAction;
 import org.elasticsearch.action.delete.DeleteRequest;
 import org.elasticsearch.cluster.ClusterService;
 import org.elasticsearch.cluster.metadata.IndexMetaData;
@@ -199,7 +200,7 @@ public class IndicesTTLService extends AbstractLifecycleComponent<IndicesTTLServ
 
     private void purgeShards(List<IndexShard> shardsToPurge) {
         for (IndexShard shardToPurge : shardsToPurge) {
-            Query query = NumericRangeQuery.newLongRange(TTLFieldMapper.NAME, null, System.currentTimeMillis(), false, true);
+            Query query = shardToPurge.indexService().mapperService().smartNameFieldMapper(TTLFieldMapper.NAME).rangeQuery(null, System.currentTimeMillis(), false, true, null);
             Engine.Searcher searcher = shardToPurge.acquireSearcher("indices_ttl");
             try {
                 logger.debug("[{}][{}] purging shard", shardToPurge.routingEntry().index(), shardToPurge.routingEntry().id());

+ 180 - 0
src/test/java/org/elasticsearch/index/mapper/numeric/SimpleNumericTests.java

@@ -19,18 +19,25 @@
 
 package org.elasticsearch.index.mapper.numeric;
 
+import org.apache.lucene.analysis.NumericTokenStream;
+import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.document.Field;
 import org.apache.lucene.index.FieldInfo.DocValuesType;
+import org.apache.lucene.index.IndexableField;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.xcontent.XContentFactory;
 import org.elasticsearch.index.mapper.*;
 import org.elasticsearch.index.mapper.ParseContext.Document;
 import org.elasticsearch.index.mapper.core.DoubleFieldMapper;
 import org.elasticsearch.index.mapper.core.LongFieldMapper;
+import org.elasticsearch.index.mapper.core.NumberFieldMapper;
 import org.elasticsearch.index.mapper.core.StringFieldMapper;
 import org.elasticsearch.index.mapper.string.SimpleStringMappingTests;
 import org.elasticsearch.test.ElasticsearchTestCase;
 import org.junit.Test;
 
+import java.io.IOException;
+
 import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
 import static org.hamcrest.Matchers.*;
 
@@ -322,4 +329,177 @@ public class SimpleNumericTests extends ElasticsearchTestCase {
             assertEquals(DocValuesType.BINARY, SimpleStringMappingTests.docValuesType(doc, "nested.double"));
         }
     }
+    
+    /** Test default precision step for autodetected numeric types */
+    @Test
+    public void testPrecisionStepDefaultsDetected() throws Exception {
+        String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
+                .field("numeric_detection", true)
+                .field("date_detection", true)
+                .endObject().endObject().string();
+
+        DocumentMapper mapper = MapperTestUtils.newParser().parse(mapping);
+
+        ParsedDocument doc = mapper.parse("type", "1", XContentFactory.jsonBuilder()
+                .startObject()
+                .field("long",   "100")
+                .field("double", "100.0")
+                .field("date",   "2010-01-01")
+                .endObject()
+                .bytes());
+        
+        assertEquals(1, doc.docs().size());
+        Document luceneDoc = doc.docs().get(0);
+        
+        assertPrecisionStepEquals(NumberFieldMapper.Defaults.PRECISION_STEP_64_BIT, luceneDoc.getField("long"));
+        assertPrecisionStepEquals(NumberFieldMapper.Defaults.PRECISION_STEP_64_BIT, luceneDoc.getField("double"));
+        assertPrecisionStepEquals(NumberFieldMapper.Defaults.PRECISION_STEP_64_BIT, luceneDoc.getField("date"));
+    }
+    
+    /** Test default precision step for numeric types */
+    @Test
+    public void testPrecisionStepDefaultsMapped() throws Exception {
+        String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
+                .startObject("properties")
+                .startObject("int")
+                    .field("type", "integer")
+                .endObject()
+                .startObject("float")
+                    .field("type", "float")
+                .endObject()
+                .startObject("long")
+                    .field("type", "long")
+                .endObject()
+                .startObject("double")
+                    .field("type", "double")
+                .endObject()
+                .startObject("short")
+                    .field("type", "short")
+                .endObject()
+                .startObject("byte")
+                    .field("type", "byte")
+                .endObject()
+                .startObject("date")
+                    .field("type", "date")
+                .endObject()
+                .startObject("ip")
+                    .field("type", "ip")
+                .endObject()
+                
+                .endObject()
+                .endObject().endObject().string();
+
+        DocumentMapper mapper = MapperTestUtils.newParser().parse(mapping);
+        
+        ParsedDocument doc = mapper.parse("type", "1", XContentFactory.jsonBuilder()
+                .startObject()
+                .field("int",    "100")
+                .field("float",  "100.0")
+                .field("long",   "5000")
+                .field("double", "34.545")
+                .field("short",  "1645")
+                .field("byte",   "50")
+                .field("date",   "2010-01-01")
+                .field("ip",     "255.255.255.255")
+                .endObject()
+                .bytes());
+        
+        assertEquals(1, doc.docs().size());
+        Document luceneDoc = doc.docs().get(0);
+        
+        assertPrecisionStepEquals(NumberFieldMapper.Defaults.PRECISION_STEP_64_BIT, luceneDoc.getField("long"));
+        assertPrecisionStepEquals(NumberFieldMapper.Defaults.PRECISION_STEP_64_BIT, luceneDoc.getField("double"));
+        assertPrecisionStepEquals(NumberFieldMapper.Defaults.PRECISION_STEP_64_BIT, luceneDoc.getField("date"));
+        assertPrecisionStepEquals(NumberFieldMapper.Defaults.PRECISION_STEP_64_BIT, luceneDoc.getField("ip"));
+        
+        assertPrecisionStepEquals(NumberFieldMapper.Defaults.PRECISION_STEP_32_BIT, luceneDoc.getField("int"));
+        assertPrecisionStepEquals(NumberFieldMapper.Defaults.PRECISION_STEP_32_BIT, luceneDoc.getField("float"));
+        
+        assertPrecisionStepEquals(NumberFieldMapper.Defaults.PRECISION_STEP_16_BIT, luceneDoc.getField("short"));
+        assertPrecisionStepEquals(NumberFieldMapper.Defaults.PRECISION_STEP_8_BIT,  luceneDoc.getField("byte"));
+    }
+    
+    /** Test precision step set to silly explicit values */
+    @Test
+    public void testPrecisionStepExplicit() throws Exception {
+        String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
+                .startObject("properties")
+                .startObject("int")
+                    .field("type", "integer")
+                    .field("precision_step", "1")
+                .endObject()
+                .startObject("float")
+                    .field("type", "float")
+                    .field("precision_step", "2")
+                .endObject()
+                .startObject("long")
+                    .field("type", "long")
+                    .field("precision_step", "1")
+                .endObject()
+                .startObject("double")
+                    .field("type", "double")
+                    .field("precision_step", "2")
+                .endObject()
+                .startObject("short")
+                    .field("type", "short")
+                    .field("precision_step", "1")
+                .endObject()
+                .startObject("byte")
+                    .field("type", "byte")
+                    .field("precision_step", "2")
+                .endObject()
+                .startObject("date")
+                    .field("type", "date")
+                    .field("precision_step", "1")
+                .endObject()
+                .startObject("ip")
+                    .field("type", "ip")
+                    .field("precision_step", "2")
+                .endObject()
+                
+                .endObject()
+                .endObject().endObject().string();
+
+        DocumentMapper mapper = MapperTestUtils.newParser().parse(mapping);
+        
+        ParsedDocument doc = mapper.parse("type", "1", XContentFactory.jsonBuilder()
+                .startObject()
+                .field("int",    "100")
+                .field("float",  "100.0")
+                .field("long",   "5000")
+                .field("double", "34.545")
+                .field("short",  "1645")
+                .field("byte",   "50")
+                .field("date",   "2010-01-01")
+                .field("ip",     "255.255.255.255")
+                .endObject()
+                .bytes());
+        
+        assertEquals(1, doc.docs().size());
+        Document luceneDoc = doc.docs().get(0);
+        
+        assertPrecisionStepEquals(1, luceneDoc.getField("int"));
+        assertPrecisionStepEquals(2, luceneDoc.getField("float"));
+        assertPrecisionStepEquals(1, luceneDoc.getField("long"));
+        assertPrecisionStepEquals(2, luceneDoc.getField("double"));
+        assertPrecisionStepEquals(1, luceneDoc.getField("short"));
+        assertPrecisionStepEquals(2, luceneDoc.getField("byte"));
+        assertPrecisionStepEquals(1, luceneDoc.getField("date"));
+        assertPrecisionStepEquals(2, luceneDoc.getField("ip"));
+
+    }
+    
+    /** checks precisionstep on both the fieldtype and the tokenstream */
+    private static void assertPrecisionStepEquals(int expected, IndexableField field) throws IOException {
+        assertNotNull(field);
+        assertThat(field, instanceOf(Field.class));
+        
+        // check fieldtype's precisionstep
+        assertEquals(expected, ((Field)field).fieldType().numericPrecisionStep());
+        
+        // check the tokenstream actually used by the indexer
+        TokenStream ts = field.tokenStream(null);
+        assertThat(ts, instanceOf(NumericTokenStream.class)); 
+        assertEquals(expected, ((NumericTokenStream)ts).getPrecisionStep());
+    }
 }

+ 5 - 4
src/test/java/org/elasticsearch/index/query/SimpleIndexQueryParserTests.java

@@ -57,6 +57,7 @@ import org.elasticsearch.index.fielddata.IndexFieldDataModule;
 import org.elasticsearch.index.fielddata.IndexFieldDataService;
 import org.elasticsearch.index.mapper.MapperService;
 import org.elasticsearch.index.mapper.MapperServiceModule;
+import org.elasticsearch.index.mapper.core.NumberFieldMapper;
 import org.elasticsearch.index.query.functionscore.FunctionScoreModule;
 import org.elasticsearch.index.search.NumericRangeFieldDataFilter;
 import org.elasticsearch.index.search.geo.GeoDistanceFilter;
@@ -1569,7 +1570,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchTestCase {
         String query = copyToStringFromClasspath("/org/elasticsearch/index/query/span-multi-term-fuzzy-range.json");
         Query parsedQuery = queryParser.parse(query).query();
         assertThat(parsedQuery, instanceOf(SpanMultiTermQueryWrapper.class));
-        NumericRangeQuery<Long> expectedWrapped = NumericRangeQuery.newLongRange("age", 7l, 17l, true, true);
+        NumericRangeQuery<Long> expectedWrapped = NumericRangeQuery.newLongRange("age", NumberFieldMapper.Defaults.PRECISION_STEP_64_BIT, 7l, 17l, true, true);
         expectedWrapped.setBoost(2.0f);
         SpanMultiTermQueryWrapper<MultiTermQuery> wrapper = (SpanMultiTermQueryWrapper<MultiTermQuery>) parsedQuery;
         assertThat(wrapper, equalTo(new SpanMultiTermQueryWrapper<MultiTermQuery>(expectedWrapped)));
@@ -1581,7 +1582,7 @@ public class SimpleIndexQueryParserTests extends ElasticsearchTestCase {
         String query = copyToStringFromClasspath("/org/elasticsearch/index/query/span-multi-term-range-numeric.json");
         Query parsedQuery = queryParser.parse(query).query();
         assertThat(parsedQuery, instanceOf(SpanMultiTermQueryWrapper.class));
-        NumericRangeQuery<Long> expectedWrapped = NumericRangeQuery.newLongRange("age", 10l, 20l, true, false);
+        NumericRangeQuery<Long> expectedWrapped = NumericRangeQuery.newLongRange("age", NumberFieldMapper.Defaults.PRECISION_STEP_64_BIT, 10l, 20l, true, false);
         expectedWrapped.setBoost(2.0f);
         SpanMultiTermQueryWrapper<MultiTermQuery> wrapper = (SpanMultiTermQueryWrapper<MultiTermQuery>) parsedQuery;
         assertThat(wrapper, equalTo(new SpanMultiTermQueryWrapper<MultiTermQuery>(expectedWrapped)));
@@ -1590,10 +1591,10 @@ public class SimpleIndexQueryParserTests extends ElasticsearchTestCase {
     @Test
     public void testSpanMultiTermTermRangeQuery() throws IOException {
         IndexQueryParserService queryParser = queryParser();
-        String query = copyToStringFromClasspath("/org/elasticsearch/index/query/span-multi-term-range-numeric.json");
+        String query = copyToStringFromClasspath("/org/elasticsearch/index/query/span-multi-term-range-term.json");
         Query parsedQuery = queryParser.parse(query).query();
         assertThat(parsedQuery, instanceOf(SpanMultiTermQueryWrapper.class));
-        NumericRangeQuery<Long> expectedWrapped = NumericRangeQuery.newLongRange("age", 10l, 20l, true, false);
+        TermRangeQuery expectedWrapped = TermRangeQuery.newStringRange("user", "alice", "bob", true, false);
         expectedWrapped.setBoost(2.0f);
         SpanMultiTermQueryWrapper<MultiTermQuery> wrapper = (SpanMultiTermQueryWrapper<MultiTermQuery>) parsedQuery;
         assertThat(wrapper, equalTo(new SpanMultiTermQueryWrapper<MultiTermQuery>(expectedWrapped)));

+ 3 - 3
src/test/java/org/elasticsearch/index/query/span-multi-term-range-term.json

@@ -2,9 +2,9 @@
 	"span_multi":{
 		"match":{
 			"range" : {
-     		   "age" : { 
-            		"from" : 10, 
-            		"to" : 20, 
+     		   "user" : { 
+            		"from" : "alice", 
+            		"to" : "bob", 
             		"include_lower" : true, 
             		"include_upper": false, 
             		"boost" : 2.0