Browse Source

Switch to Lucene's new IntField/LongField/FloatField/DoubleField. (#93165)

Lucene introduced new numeric fields that index both points and doc
values. This has the same semantics as indexing one field for points and
another one for doc values as we did before, but covering both data
structures in a single field yielded a speedup in Lucene's nightly
benchmarks (see annotation
[AH](http://people.apache.org/~mikemccand/lucenebench/sparseResults.html#index_throughput))
which would be interesting to get too.

This commit does not switch to factory methods for queries such as
`LongField#newRangeQuery` for now, we'll need to look into it in a
follow-up.
Adrien Grand 2 years ago
parent
commit
c21ee47610
18 changed files with 161 additions and 205 deletions
  1. 5 0
      docs/changelog/93165.yaml
  2. 1 1
      modules/data-streams/src/test/java/org/elasticsearch/datastreams/mapper/DataStreamTimestampFieldMapperTests.java
  3. 9 30
      modules/mapper-extras/src/test/java/org/elasticsearch/index/mapper/extras/ScaledFloatFieldMapperTests.java
  4. 10 6
      server/src/main/java/org/elasticsearch/index/mapper/DateFieldMapper.java
  5. 24 16
      server/src/main/java/org/elasticsearch/index/mapper/NumberFieldMapper.java
  6. 5 1
      server/src/test/java/org/elasticsearch/index/mapper/CopyToMapperTests.java
  7. 32 40
      server/src/test/java/org/elasticsearch/index/mapper/DateFieldMapperTests.java
  8. 3 5
      server/src/test/java/org/elasticsearch/index/mapper/DateScriptMapperTests.java
  9. 25 29
      server/src/test/java/org/elasticsearch/index/mapper/DocumentParserTests.java
  10. 3 5
      server/src/test/java/org/elasticsearch/index/mapper/DoubleScriptMapperTests.java
  11. 1 1
      server/src/test/java/org/elasticsearch/index/mapper/DynamicMappingTests.java
  12. 6 7
      server/src/test/java/org/elasticsearch/index/mapper/IndexTimeScriptTests.java
  13. 2 2
      server/src/test/java/org/elasticsearch/index/mapper/LongFieldMapperTests.java
  14. 3 5
      server/src/test/java/org/elasticsearch/index/mapper/LongScriptMapperTests.java
  15. 16 23
      server/src/test/java/org/elasticsearch/index/mapper/NumberFieldMapperTests.java
  16. 1 1
      x-pack/plugin/mapper-aggregate-metric/src/test/java/org/elasticsearch/xpack/aggregatemetric/mapper/AggregateDoubleMetricFieldMapperTests.java
  17. 6 4
      x-pack/plugin/mapper-unsigned-long/src/main/java/org/elasticsearch/xpack/unsignedlong/UnsignedLongFieldMapper.java
  18. 9 29
      x-pack/plugin/mapper-unsigned-long/src/test/java/org/elasticsearch/xpack/unsignedlong/UnsignedLongFieldMapperTests.java

+ 5 - 0
docs/changelog/93165.yaml

@@ -0,0 +1,5 @@
+pr: 93165
+summary: Switch to Lucene's new `IntField/LongField/FloatField/DoubleField`
+area: Mapping
+type: enhancement
+issues: []

+ 1 - 1
modules/data-streams/src/test/java/org/elasticsearch/datastreams/mapper/DataStreamTimestampFieldMapperTests.java

@@ -79,7 +79,7 @@ public class DataStreamTimestampFieldMapperTests extends MetadataMapperTestCase
         }));
         }));
 
 
         ParsedDocument doc = docMapper.parse(source(b -> b.field("@timestamp", "2020-12-12")));
         ParsedDocument doc = docMapper.parse(source(b -> b.field("@timestamp", "2020-12-12")));
-        assertThat(doc.rootDoc().getFields("@timestamp").length, equalTo(2));
+        assertThat(doc.rootDoc().getFields("@timestamp").length, equalTo(1));
 
 
         Exception e = expectThrows(MapperException.class, () -> docMapper.parse(source(b -> b.field("@timestamp1", "2020-12-12"))));
         Exception e = expectThrows(MapperException.class, () -> docMapper.parse(source(b -> b.field("@timestamp1", "2020-12-12"))));
         assertThat(e.getCause().getMessage(), equalTo("data stream timestamp field [@timestamp] is missing"));
         assertThat(e.getCause().getMessage(), equalTo("data stream timestamp field [@timestamp] is missing"));

+ 9 - 30
modules/mapper-extras/src/test/java/org/elasticsearch/index/mapper/extras/ScaledFloatFieldMapperTests.java

@@ -94,15 +94,8 @@ public class ScaledFloatFieldMapperTests extends MapperTestCase {
 
 
         ParsedDocument doc = mapper.parse(source(b -> b.field("field", 123)));
         ParsedDocument doc = mapper.parse(source(b -> b.field("field", 123)));
         IndexableField[] fields = doc.rootDoc().getFields("field");
         IndexableField[] fields = doc.rootDoc().getFields("field");
-        assertEquals(2, fields.length);
-        IndexableField pointField = fields[0];
-        assertEquals(1, pointField.fieldType().pointDimensionCount());
-        assertFalse(pointField.fieldType().stored());
-        assertEquals(1230, pointField.numericValue().longValue());
-        IndexableField dvField = fields[1];
-        assertEquals(DocValuesType.SORTED_NUMERIC, dvField.fieldType().docValuesType());
-        assertEquals(1230, dvField.numericValue().longValue());
-        assertFalse(dvField.fieldType().stored());
+        assertEquals(1, fields.length);
+        assertEquals("LongField <field:1230>", fields[0].toString());
     }
     }
 
 
     public void testMissingScalingFactor() {
     public void testMissingScalingFactor() {
@@ -175,13 +168,9 @@ public class ScaledFloatFieldMapperTests extends MapperTestCase {
         );
         );
 
 
         IndexableField[] fields = doc.rootDoc().getFields("field");
         IndexableField[] fields = doc.rootDoc().getFields("field");
-        assertEquals(3, fields.length);
-        IndexableField pointField = fields[0];
-        assertEquals(1, pointField.fieldType().pointDimensionCount());
-        assertEquals(1230, pointField.numericValue().doubleValue(), 0d);
-        IndexableField dvField = fields[1];
-        assertEquals(DocValuesType.SORTED_NUMERIC, dvField.fieldType().docValuesType());
-        IndexableField storedField = fields[2];
+        assertEquals(2, fields.length);
+        assertEquals("LongField <field:1230>", fields[0].toString());
+        IndexableField storedField = fields[1];
         assertTrue(storedField.fieldType().stored());
         assertTrue(storedField.fieldType().stored());
         assertEquals(1230, storedField.numericValue().longValue());
         assertEquals(1230, storedField.numericValue().longValue());
     }
     }
@@ -196,12 +185,8 @@ public class ScaledFloatFieldMapperTests extends MapperTestCase {
             )
             )
         );
         );
         IndexableField[] fields = doc.rootDoc().getFields("field");
         IndexableField[] fields = doc.rootDoc().getFields("field");
-        assertEquals(2, fields.length);
-        IndexableField pointField = fields[0];
-        assertEquals(1, pointField.fieldType().pointDimensionCount());
-        assertEquals(1230, pointField.numericValue().longValue());
-        IndexableField dvField = fields[1];
-        assertEquals(DocValuesType.SORTED_NUMERIC, dvField.fieldType().docValuesType());
+        assertEquals(1, fields.length);
+        assertEquals("LongField <field:1230>", fields[0].toString());
 
 
         DocumentMapper mapper2 = createDocumentMapper(
         DocumentMapper mapper2 = createDocumentMapper(
             fieldMapping(b -> b.field("type", "scaled_float").field("scaling_factor", 10.0).field("coerce", false))
             fieldMapping(b -> b.field("type", "scaled_float").field("scaling_factor", 10.0).field("coerce", false))
@@ -254,14 +239,8 @@ public class ScaledFloatFieldMapperTests extends MapperTestCase {
             )
             )
         );
         );
         IndexableField[] fields = doc.rootDoc().getFields("field");
         IndexableField[] fields = doc.rootDoc().getFields("field");
-        assertEquals(2, fields.length);
-        IndexableField pointField = fields[0];
-        assertEquals(1, pointField.fieldType().pointDimensionCount());
-        assertFalse(pointField.fieldType().stored());
-        assertEquals(25, pointField.numericValue().longValue());
-        IndexableField dvField = fields[1];
-        assertEquals(DocValuesType.SORTED_NUMERIC, dvField.fieldType().docValuesType());
-        assertFalse(dvField.fieldType().stored());
+        assertEquals(1, fields.length);
+        assertEquals("LongField <field:25>", fields[0].toString());
     }
     }
 
 
     /**
     /**

+ 10 - 6
server/src/main/java/org/elasticsearch/index/mapper/DateFieldMapper.java

@@ -10,6 +10,7 @@ package org.elasticsearch.index.mapper;
 
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.Logger;
+import org.apache.lucene.document.LongField;
 import org.apache.lucene.document.LongPoint;
 import org.apache.lucene.document.LongPoint;
 import org.apache.lucene.document.SortedNumericDocValuesField;
 import org.apache.lucene.document.SortedNumericDocValuesField;
 import org.apache.lucene.document.StoredField;
 import org.apache.lucene.document.StoredField;
@@ -907,17 +908,20 @@ public final class DateFieldMapper extends FieldMapper {
     }
     }
 
 
     private void indexValue(DocumentParserContext context, long timestamp) {
     private void indexValue(DocumentParserContext context, long timestamp) {
-        if (indexed) {
-            context.doc().add(new LongPoint(fieldType().name(), timestamp));
-        }
-        if (hasDocValues) {
+        if (indexed && hasDocValues) {
+            context.doc().add(new LongField(fieldType().name(), timestamp));
+        } else if (hasDocValues) {
             context.doc().add(new SortedNumericDocValuesField(fieldType().name(), timestamp));
             context.doc().add(new SortedNumericDocValuesField(fieldType().name(), timestamp));
-        } else if (store || indexed) {
-            context.addToFieldNames(fieldType().name());
+        } else if (indexed) {
+            context.doc().add(new LongPoint(fieldType().name(), timestamp));
         }
         }
         if (store) {
         if (store) {
             context.doc().add(new StoredField(fieldType().name(), timestamp));
             context.doc().add(new StoredField(fieldType().name(), timestamp));
         }
         }
+        if (hasDocValues == false && (indexed || store)) {
+            // When the field doesn't have doc values so that we can run exists queries, we also need to index the field name separately.
+            context.addToFieldNames(fieldType().name());
+        }
     }
     }
 
 
     @Override
     @Override

+ 24 - 16
server/src/main/java/org/elasticsearch/index/mapper/NumberFieldMapper.java

@@ -8,9 +8,13 @@
 
 
 package org.elasticsearch.index.mapper;
 package org.elasticsearch.index.mapper;
 
 
+import org.apache.lucene.document.DoubleField;
 import org.apache.lucene.document.DoublePoint;
 import org.apache.lucene.document.DoublePoint;
+import org.apache.lucene.document.FloatField;
 import org.apache.lucene.document.FloatPoint;
 import org.apache.lucene.document.FloatPoint;
+import org.apache.lucene.document.IntField;
 import org.apache.lucene.document.IntPoint;
 import org.apache.lucene.document.IntPoint;
+import org.apache.lucene.document.LongField;
 import org.apache.lucene.document.LongPoint;
 import org.apache.lucene.document.LongPoint;
 import org.apache.lucene.document.SortedNumericDocValuesField;
 import org.apache.lucene.document.SortedNumericDocValuesField;
 import org.apache.lucene.document.StoredField;
 import org.apache.lucene.document.StoredField;
@@ -544,11 +548,12 @@ public class NumberFieldMapper extends FieldMapper {
             @Override
             @Override
             public void addFields(LuceneDocument document, String name, Number value, boolean indexed, boolean docValued, boolean stored) {
             public void addFields(LuceneDocument document, String name, Number value, boolean indexed, boolean docValued, boolean stored) {
                 final float f = value.floatValue();
                 final float f = value.floatValue();
-                if (indexed) {
-                    document.add(new FloatPoint(name, f));
-                }
-                if (docValued) {
+                if (indexed && docValued) {
+                    document.add(new FloatField(name, f));
+                } else if (docValued) {
                     document.add(new SortedNumericDocValuesField(name, NumericUtils.floatToSortableInt(f)));
                     document.add(new SortedNumericDocValuesField(name, NumericUtils.floatToSortableInt(f)));
+                } else if (indexed) {
+                    document.add(new FloatPoint(name, f));
                 }
                 }
                 if (stored) {
                 if (stored) {
                     document.add(new StoredField(name, f));
                     document.add(new StoredField(name, f));
@@ -673,11 +678,12 @@ public class NumberFieldMapper extends FieldMapper {
             @Override
             @Override
             public void addFields(LuceneDocument document, String name, Number value, boolean indexed, boolean docValued, boolean stored) {
             public void addFields(LuceneDocument document, String name, Number value, boolean indexed, boolean docValued, boolean stored) {
                 final double d = value.doubleValue();
                 final double d = value.doubleValue();
-                if (indexed) {
-                    document.add(new DoublePoint(name, d));
-                }
-                if (docValued) {
+                if (indexed && docValued) {
+                    document.add(new DoubleField(name, d));
+                } else if (docValued) {
                     document.add(new SortedNumericDocValuesField(name, NumericUtils.doubleToSortableLong(d)));
                     document.add(new SortedNumericDocValuesField(name, NumericUtils.doubleToSortableLong(d)));
+                } else if (indexed) {
+                    document.add(new DoublePoint(name, d));
                 }
                 }
                 if (stored) {
                 if (stored) {
                     document.add(new StoredField(name, d));
                     document.add(new StoredField(name, d));
@@ -1022,11 +1028,12 @@ public class NumberFieldMapper extends FieldMapper {
             @Override
             @Override
             public void addFields(LuceneDocument document, String name, Number value, boolean indexed, boolean docValued, boolean stored) {
             public void addFields(LuceneDocument document, String name, Number value, boolean indexed, boolean docValued, boolean stored) {
                 final int i = value.intValue();
                 final int i = value.intValue();
-                if (indexed) {
-                    document.add(new IntPoint(name, i));
-                }
-                if (docValued) {
+                if (indexed && docValued) {
+                    document.add(new IntField(name, i));
+                } else if (docValued) {
                     document.add(new SortedNumericDocValuesField(name, i));
                     document.add(new SortedNumericDocValuesField(name, i));
+                } else if (indexed) {
+                    document.add(new IntPoint(name, i));
                 }
                 }
                 if (stored) {
                 if (stored) {
                     document.add(new StoredField(name, i));
                     document.add(new StoredField(name, i));
@@ -1148,11 +1155,12 @@ public class NumberFieldMapper extends FieldMapper {
             @Override
             @Override
             public void addFields(LuceneDocument document, String name, Number value, boolean indexed, boolean docValued, boolean stored) {
             public void addFields(LuceneDocument document, String name, Number value, boolean indexed, boolean docValued, boolean stored) {
                 final long l = value.longValue();
                 final long l = value.longValue();
-                if (indexed) {
-                    document.add(new LongPoint(name, l));
-                }
-                if (docValued) {
+                if (indexed && docValued) {
+                    document.add(new LongField(name, l));
+                } else if (docValued) {
                     document.add(new SortedNumericDocValuesField(name, l));
                     document.add(new SortedNumericDocValuesField(name, l));
+                } else if (indexed) {
+                    document.add(new LongPoint(name, l));
                 }
                 }
                 if (stored) {
                 if (stored) {
                     document.add(new StoredField(name, l));
                     document.add(new StoredField(name, l));

+ 5 - 1
server/src/test/java/org/elasticsearch/index/mapper/CopyToMapperTests.java

@@ -8,6 +8,7 @@
 
 
 package org.elasticsearch.index.mapper;
 package org.elasticsearch.index.mapper;
 
 
+import org.apache.lucene.index.DocValuesType;
 import org.apache.lucene.index.IndexableField;
 import org.apache.lucene.index.IndexableField;
 import org.elasticsearch.common.bytes.BytesReference;
 import org.elasticsearch.common.bytes.BytesReference;
 import org.elasticsearch.xcontent.ToXContent;
 import org.elasticsearch.xcontent.ToXContent;
@@ -91,9 +92,12 @@ public class CopyToMapperTests extends MapperServiceTestCase {
         assertThat(doc.getFields("cyclic_test")[1].stringValue(), equalTo("bar"));
         assertThat(doc.getFields("cyclic_test")[1].stringValue(), equalTo("bar"));
 
 
         assertThat(doc.getFields("int_to_str_test").length, equalTo(1));
         assertThat(doc.getFields("int_to_str_test").length, equalTo(1));
+        assertThat(doc.getFields("int_to_str_test")[0].fieldType().docValuesType(), equalTo(DocValuesType.NONE));
         assertThat(doc.getFields("int_to_str_test")[0].numericValue().intValue(), equalTo(42));
         assertThat(doc.getFields("int_to_str_test")[0].numericValue().intValue(), equalTo(42));
 
 
-        assertThat(doc.getFields("new_field").length, equalTo(2)); // new field has doc values
+        assertThat(doc.getFields("new_field").length, equalTo(1));
+        // new_field has doc values
+        assertThat(doc.getFields("new_field")[0].fieldType().docValuesType(), equalTo(DocValuesType.SORTED_NUMERIC));
         assertThat(doc.getFields("new_field")[0].numericValue().intValue(), equalTo(42));
         assertThat(doc.getFields("new_field")[0].numericValue().intValue(), equalTo(42));
 
 
         assertNotNull(parsedDoc.dynamicMappingsUpdate());
         assertNotNull(parsedDoc.dynamicMappingsUpdate());

+ 32 - 40
server/src/test/java/org/elasticsearch/index/mapper/DateFieldMapperTests.java

@@ -89,16 +89,14 @@ public class DateFieldMapperTests extends MapperTestCase {
         ParsedDocument doc = mapper.parse(source(b -> b.field("field", "2016-03-11")));
         ParsedDocument doc = mapper.parse(source(b -> b.field("field", "2016-03-11")));
 
 
         IndexableField[] fields = doc.rootDoc().getFields("field");
         IndexableField[] fields = doc.rootDoc().getFields("field");
-        assertEquals(2, fields.length);
-        IndexableField pointField = fields[0];
-        assertEquals(1, pointField.fieldType().pointIndexDimensionCount());
-        assertEquals(8, pointField.fieldType().pointNumBytes());
-        assertFalse(pointField.fieldType().stored());
-        assertEquals(1457654400000L, pointField.numericValue().longValue());
-        IndexableField dvField = fields[1];
-        assertEquals(DocValuesType.SORTED_NUMERIC, dvField.fieldType().docValuesType());
-        assertEquals(1457654400000L, dvField.numericValue().longValue());
-        assertFalse(dvField.fieldType().stored());
+        assertEquals(1, fields.length);
+        IndexableField field = fields[0];
+        assertEquals(1, field.fieldType().pointIndexDimensionCount());
+        assertEquals(8, field.fieldType().pointNumBytes());
+        assertFalse(field.fieldType().stored());
+        assertEquals("LongField <field:1457654400000>", field.toString());
+        assertEquals(DocValuesType.SORTED_NUMERIC, field.fieldType().docValuesType());
+        assertFalse(field.fieldType().stored());
     }
     }
 
 
     public void testNotIndexed() throws Exception {
     public void testNotIndexed() throws Exception {
@@ -132,12 +130,11 @@ public class DateFieldMapperTests extends MapperTestCase {
         ParsedDocument doc = mapper.parse(source(b -> b.field("field", "2016-03-11")));
         ParsedDocument doc = mapper.parse(source(b -> b.field("field", "2016-03-11")));
 
 
         IndexableField[] fields = doc.rootDoc().getFields("field");
         IndexableField[] fields = doc.rootDoc().getFields("field");
-        assertEquals(3, fields.length);
-        IndexableField pointField = fields[0];
-        assertEquals(1, pointField.fieldType().pointIndexDimensionCount());
-        IndexableField dvField = fields[1];
-        assertEquals(DocValuesType.SORTED_NUMERIC, dvField.fieldType().docValuesType());
-        IndexableField storedField = fields[2];
+        assertEquals(2, fields.length);
+        IndexableField field = fields[0];
+        assertEquals(1, field.fieldType().pointIndexDimensionCount());
+        assertEquals(DocValuesType.SORTED_NUMERIC, field.fieldType().docValuesType());
+        IndexableField storedField = fields[1];
         assertTrue(storedField.fieldType().stored());
         assertTrue(storedField.fieldType().stored());
         assertEquals(1457654400000L, storedField.numericValue().longValue());
         assertEquals(1457654400000L, storedField.numericValue().longValue());
     }
     }
@@ -170,9 +167,9 @@ public class DateFieldMapperTests extends MapperTestCase {
         ParsedDocument doc = mapper.parse(source(b -> b.field("field", 1457654400)));
         ParsedDocument doc = mapper.parse(source(b -> b.field("field", 1457654400)));
 
 
         IndexableField[] fields = doc.rootDoc().getFields("field");
         IndexableField[] fields = doc.rootDoc().getFields("field");
-        assertEquals(2, fields.length);
-        IndexableField pointField = fields[0];
-        assertEquals(1457654400000L, pointField.numericValue().longValue());
+        assertEquals(1, fields.length);
+        IndexableField field = fields[0];
+        assertEquals(1457654400000L, field.numericValue().longValue());
     }
     }
 
 
     public void testChangeLocale() throws IOException {
     public void testChangeLocale() throws IOException {
@@ -194,16 +191,14 @@ public class DateFieldMapperTests extends MapperTestCase {
 
 
         doc = mapper.parse(source(b -> b.nullField("field")));
         doc = mapper.parse(source(b -> b.nullField("field")));
         IndexableField[] fields = doc.rootDoc().getFields("field");
         IndexableField[] fields = doc.rootDoc().getFields("field");
-        assertEquals(2, fields.length);
-        IndexableField pointField = fields[0];
-        assertEquals(1, pointField.fieldType().pointIndexDimensionCount());
-        assertEquals(8, pointField.fieldType().pointNumBytes());
-        assertFalse(pointField.fieldType().stored());
-        assertEquals(1457654400000L, pointField.numericValue().longValue());
-        IndexableField dvField = fields[1];
-        assertEquals(DocValuesType.SORTED_NUMERIC, dvField.fieldType().docValuesType());
-        assertEquals(1457654400000L, dvField.numericValue().longValue());
-        assertFalse(dvField.fieldType().stored());
+        assertEquals(1, fields.length);
+        IndexableField field = fields[0];
+        assertEquals(1, field.fieldType().pointIndexDimensionCount());
+        assertEquals(8, field.fieldType().pointNumBytes());
+        assertEquals("LongField <field:1457654400000>", field.toString());
+        assertEquals(DocValuesType.SORTED_NUMERIC, field.fieldType().docValuesType());
+        assertEquals(1457654400000L, field.numericValue().longValue());
+        assertFalse(field.fieldType().stored());
     }
     }
 
 
     public void testNanosNullValue() throws IOException {
     public void testNanosNullValue() throws IOException {
@@ -221,16 +216,13 @@ public class DateFieldMapperTests extends MapperTestCase {
 
 
         doc = mapperService.documentMapper().parse(source(b -> b.nullField("field")));
         doc = mapperService.documentMapper().parse(source(b -> b.nullField("field")));
         IndexableField[] fields = doc.rootDoc().getFields("field");
         IndexableField[] fields = doc.rootDoc().getFields("field");
-        assertEquals(2, fields.length);
-        IndexableField pointField = fields[0];
-        assertEquals(1, pointField.fieldType().pointIndexDimensionCount());
-        assertEquals(8, pointField.fieldType().pointNumBytes());
-        assertFalse(pointField.fieldType().stored());
-        assertEquals(expectedNullValue, pointField.numericValue().longValue());
-        IndexableField dvField = fields[1];
-        assertEquals(DocValuesType.SORTED_NUMERIC, dvField.fieldType().docValuesType());
-        assertEquals(expectedNullValue, dvField.numericValue().longValue());
-        assertFalse(dvField.fieldType().stored());
+        assertEquals(1, fields.length);
+        IndexableField field = fields[0];
+        assertEquals(1, field.fieldType().pointIndexDimensionCount());
+        assertEquals(8, field.fieldType().pointNumBytes());
+        assertEquals(DocValuesType.SORTED_NUMERIC, field.fieldType().docValuesType());
+        assertEquals(expectedNullValue, field.numericValue().longValue());
+        assertFalse(field.fieldType().stored());
     }
     }
 
 
     public void testBadNullValue() throws IOException {
     public void testBadNullValue() throws IOException {
@@ -273,7 +265,7 @@ public class DateFieldMapperTests extends MapperTestCase {
         ParsedDocument doc = mapper.parse(source(b -> b.field("field", formatter.format(randomDate))));
         ParsedDocument doc = mapper.parse(source(b -> b.field("field", formatter.format(randomDate))));
 
 
         IndexableField[] fields = doc.rootDoc().getFields("field");
         IndexableField[] fields = doc.rootDoc().getFields("field");
-        assertEquals(2, fields.length);
+        assertEquals(1, fields.length);
 
 
         long millis = randomDate.withZoneSameInstant(ZoneOffset.UTC).toInstant().toEpochMilli();
         long millis = randomDate.withZoneSameInstant(ZoneOffset.UTC).toInstant().toEpochMilli();
         assertEquals(millis, fields[0].numericValue().longValue());
         assertEquals(millis, fields[0].numericValue().longValue());

+ 3 - 5
server/src/test/java/org/elasticsearch/index/mapper/DateScriptMapperTests.java

@@ -74,11 +74,9 @@ public class DateScriptMapperTests extends MapperScriptTestCase<DateFieldScript.
 
 
     @Override
     @Override
     protected void assertMultipleValues(IndexableField[] fields) {
     protected void assertMultipleValues(IndexableField[] fields) {
-        assertEquals(4, fields.length);
-        assertEquals("LongPoint <field:1516729294000>", fields[0].toString());
-        assertEquals("docValuesType=SORTED_NUMERIC<field:1516729294000>", fields[1].toString());
-        assertEquals("LongPoint <field:1516729295000>", fields[2].toString());
-        assertEquals("docValuesType=SORTED_NUMERIC<field:1516729295000>", fields[3].toString());
+        assertEquals(2, fields.length);
+        assertEquals("LongField <field:1516729294000>", fields[0].toString());
+        assertEquals("LongField <field:1516729295000>", fields[1].toString());
     }
     }
 
 
     @Override
     @Override

+ 25 - 29
server/src/test/java/org/elasticsearch/index/mapper/DocumentParserTests.java

@@ -269,8 +269,8 @@ public class DocumentParserTests extends MapperServiceTestCase {
 
 
             assertNotNull(doc.rootDoc().getField("timestamp"));
             assertNotNull(doc.rootDoc().getField("timestamp"));
             assertNotNull(doc.rootDoc().getField("_source"));
             assertNotNull(doc.rootDoc().getField("_source"));
-            assertThat(doc.rootDoc().getFields("location.lat").length, equalTo(4));
-            assertThat(doc.rootDoc().getFields("location.lon").length, equalTo(4));
+            assertThat(doc.rootDoc().getFields("location.lat").length, equalTo(2));
+            assertThat(doc.rootDoc().getFields("location.lon").length, equalTo(2));
             assertNotNull(doc.rootDoc().getField("concrete"));
             assertNotNull(doc.rootDoc().getField("concrete"));
             assertNull(doc.rootDoc().getField("country"));
             assertNull(doc.rootDoc().getField("country"));
         }
         }
@@ -290,8 +290,8 @@ public class DocumentParserTests extends MapperServiceTestCase {
 
 
             assertNotNull(doc.rootDoc().getField("timestamp"));
             assertNotNull(doc.rootDoc().getField("timestamp"));
             assertNotNull(doc.rootDoc().getField("_source"));
             assertNotNull(doc.rootDoc().getField("_source"));
-            assertThat(doc.rootDoc().getFields("location.lat").length, equalTo(4));
-            assertThat(doc.rootDoc().getFields("location.lon").length, equalTo(4));
+            assertThat(doc.rootDoc().getFields("location.lat").length, equalTo(2));
+            assertThat(doc.rootDoc().getFields("location.lon").length, equalTo(2));
             assertNotNull(doc.rootDoc().getField("concrete"));
             assertNotNull(doc.rootDoc().getField("concrete"));
             assertNull(doc.rootDoc().getField("country"));
             assertNull(doc.rootDoc().getField("country"));
         }
         }
@@ -382,13 +382,10 @@ public class DocumentParserTests extends MapperServiceTestCase {
         assertNull(doc.dynamicMappingsUpdate()); // no update!
         assertNull(doc.dynamicMappingsUpdate()); // no update!
 
 
         IndexableField[] fields = doc.rootDoc().getFields("foo.bar.baz");
         IndexableField[] fields = doc.rootDoc().getFields("foo.bar.baz");
-        assertEquals(6, fields.length);
-        assertEquals(123, fields[0].numericValue());
-        assertEquals("123", fields[1].stringValue());
-        assertEquals(456, fields[2].numericValue());
-        assertEquals("456", fields[3].stringValue());
-        assertEquals(789, fields[4].numericValue());
-        assertEquals("789", fields[5].stringValue());
+        assertEquals(3, fields.length);
+        assertEquals("IntField <foo.bar.baz:123>", fields[0].toString());
+        assertEquals("IntField <foo.bar.baz:456>", fields[1].toString());
+        assertEquals("IntField <foo.bar.baz:789>", fields[2].toString());
     }
     }
 
 
     public void testDotsWithExistingNestedMapper() throws Exception {
     public void testDotsWithExistingNestedMapper() throws Exception {
@@ -803,13 +800,13 @@ public class DocumentParserTests extends MapperServiceTestCase {
         }));
         }));
 
 
         ParsedDocument doc = mapper.parse(source(b -> b.startArray("foo").value(0).value(1).endArray()));
         ParsedDocument doc = mapper.parse(source(b -> b.startArray("foo").value(0).value(1).endArray()));
-        assertEquals(4, doc.rootDoc().getFields("foo").length);
+        assertEquals(2, doc.rootDoc().getFields("foo").length);
     }
     }
 
 
     public void testDynamicLongArray() throws Exception {
     public void testDynamicLongArray() throws Exception {
         DocumentMapper mapper = createDocumentMapper(mapping(b -> {}));
         DocumentMapper mapper = createDocumentMapper(mapping(b -> {}));
         ParsedDocument doc = mapper.parse(source(b -> b.startArray("foo").value(0).value(1).endArray()));
         ParsedDocument doc = mapper.parse(source(b -> b.startArray("foo").value(0).value(1).endArray()));
-        assertEquals(4, doc.rootDoc().getFields("foo").length);
+        assertEquals(2, doc.rootDoc().getFields("foo").length);
     }
     }
 
 
     public void testDynamicFalseLongArray() throws Exception {
     public void testDynamicFalseLongArray() throws Exception {
@@ -891,7 +888,7 @@ public class DocumentParserTests extends MapperServiceTestCase {
     public void testMappedLongArray() throws Exception {
     public void testMappedLongArray() throws Exception {
         DocumentMapper mapper = createDocumentMapper(fieldMapping(b -> b.field("type", "long")));
         DocumentMapper mapper = createDocumentMapper(fieldMapping(b -> b.field("type", "long")));
         ParsedDocument doc = mapper.parse(source(b -> b.startArray("field").value(0).value(1).endArray()));
         ParsedDocument doc = mapper.parse(source(b -> b.startArray("field").value(0).value(1).endArray()));
-        assertEquals(4, doc.rootDoc().getFields("field").length);
+        assertEquals(2, doc.rootDoc().getFields("field").length);
     }
     }
 
 
     public void testDynamicObjectWithTemplate() throws Exception {
     public void testDynamicObjectWithTemplate() throws Exception {
@@ -1033,7 +1030,7 @@ public class DocumentParserTests extends MapperServiceTestCase {
         DocumentMapper mapper = createDocumentMapper(mapping(b -> {}));
         DocumentMapper mapper = createDocumentMapper(mapping(b -> {}));
 
 
         ParsedDocument doc = mapper.parse(source(b -> b.startArray("foo.bar.baz").value(0).value(1).endArray()));
         ParsedDocument doc = mapper.parse(source(b -> b.startArray("foo.bar.baz").value(0).value(1).endArray()));
-        assertEquals(4, doc.rootDoc().getFields("foo.bar.baz").length);
+        assertEquals(2, doc.rootDoc().getFields("foo.bar.baz").length);
         Mapper fooMapper = doc.dynamicMappingsUpdate().getRoot().getMapper("foo");
         Mapper fooMapper = doc.dynamicMappingsUpdate().getRoot().getMapper("foo");
         assertNotNull(fooMapper);
         assertNotNull(fooMapper);
         assertThat(fooMapper, instanceOf(ObjectMapper.class));
         assertThat(fooMapper, instanceOf(ObjectMapper.class));
@@ -1064,7 +1061,7 @@ public class DocumentParserTests extends MapperServiceTestCase {
         }));
         }));
 
 
         ParsedDocument doc = mapper.parse(source(b -> b.startArray("foo.bar.baz").value(0).value(1).endArray()));
         ParsedDocument doc = mapper.parse(source(b -> b.startArray("foo.bar.baz").value(0).value(1).endArray()));
-        assertEquals(4, doc.rootDoc().getFields("foo.bar.baz").length);
+        assertEquals(2, doc.rootDoc().getFields("foo.bar.baz").length);
         Mapper fooMapper = doc.dynamicMappingsUpdate().getRoot().getMapper("foo");
         Mapper fooMapper = doc.dynamicMappingsUpdate().getRoot().getMapper("foo");
         assertNotNull(fooMapper);
         assertNotNull(fooMapper);
         assertThat(fooMapper, instanceOf(ObjectMapper.class));
         assertThat(fooMapper, instanceOf(ObjectMapper.class));
@@ -1240,7 +1237,7 @@ public class DocumentParserTests extends MapperServiceTestCase {
         DocumentMapper mapper = createDocumentMapper(fieldMapping(b -> b.field("type", "object")));
         DocumentMapper mapper = createDocumentMapper(fieldMapping(b -> b.field("type", "object")));
         ParsedDocument doc = mapper.parse(source(b -> b.startArray("field.bar.baz").value(0).value(1).endArray()));
         ParsedDocument doc = mapper.parse(source(b -> b.startArray("field.bar.baz").value(0).value(1).endArray()));
 
 
-        assertEquals(4, doc.rootDoc().getFields("field.bar.baz").length);
+        assertEquals(2, doc.rootDoc().getFields("field.bar.baz").length);
         Mapper fooMapper = doc.dynamicMappingsUpdate().getRoot().getMapper("field");
         Mapper fooMapper = doc.dynamicMappingsUpdate().getRoot().getMapper("field");
         assertNotNull(fooMapper);
         assertNotNull(fooMapper);
         assertThat(fooMapper, instanceOf(ObjectMapper.class));
         assertThat(fooMapper, instanceOf(ObjectMapper.class));
@@ -1279,7 +1276,7 @@ public class DocumentParserTests extends MapperServiceTestCase {
     public void testDynamicDottedFieldNameLong() throws Exception {
     public void testDynamicDottedFieldNameLong() throws Exception {
         DocumentMapper mapper = createDocumentMapper(mapping(b -> {}));
         DocumentMapper mapper = createDocumentMapper(mapping(b -> {}));
         ParsedDocument doc = mapper.parse(source(b -> b.field("foo.bar.baz", 0)));
         ParsedDocument doc = mapper.parse(source(b -> b.field("foo.bar.baz", 0)));
-        assertEquals(2, doc.rootDoc().getFields("foo.bar.baz").length);
+        assertEquals(1, doc.rootDoc().getFields("foo.bar.baz").length);
         Mapper fooMapper = doc.dynamicMappingsUpdate().getRoot().getMapper("foo");
         Mapper fooMapper = doc.dynamicMappingsUpdate().getRoot().getMapper("foo");
         assertNotNull(fooMapper);
         assertNotNull(fooMapper);
         assertThat(fooMapper, instanceOf(ObjectMapper.class));
         assertThat(fooMapper, instanceOf(ObjectMapper.class));
@@ -1310,7 +1307,7 @@ public class DocumentParserTests extends MapperServiceTestCase {
         }));
         }));
 
 
         ParsedDocument doc = mapper.parse(source(b -> b.field("foo.bar.baz", 0)));
         ParsedDocument doc = mapper.parse(source(b -> b.field("foo.bar.baz", 0)));
-        assertEquals(2, doc.rootDoc().getFields("foo.bar.baz").length);
+        assertEquals(1, doc.rootDoc().getFields("foo.bar.baz").length);
         Mapper fooMapper = doc.dynamicMappingsUpdate().getRoot().getMapper("foo");
         Mapper fooMapper = doc.dynamicMappingsUpdate().getRoot().getMapper("foo");
         assertNotNull(fooMapper);
         assertNotNull(fooMapper);
         assertThat(fooMapper, instanceOf(ObjectMapper.class));
         assertThat(fooMapper, instanceOf(ObjectMapper.class));
@@ -1325,7 +1322,7 @@ public class DocumentParserTests extends MapperServiceTestCase {
     public void testDynamicDottedFieldNameLongWithExistingParent() throws Exception {
     public void testDynamicDottedFieldNameLongWithExistingParent() throws Exception {
         DocumentMapper mapper = createDocumentMapper(fieldMapping(b -> b.field("type", "object")));
         DocumentMapper mapper = createDocumentMapper(fieldMapping(b -> b.field("type", "object")));
         ParsedDocument doc = mapper.parse(source(b -> b.field("field.bar.baz", 0)));
         ParsedDocument doc = mapper.parse(source(b -> b.field("field.bar.baz", 0)));
-        assertEquals(2, doc.rootDoc().getFields("field.bar.baz").length);
+        assertEquals(1, doc.rootDoc().getFields("field.bar.baz").length);
         Mapper fooMapper = doc.dynamicMappingsUpdate().getRoot().getMapper("field");
         Mapper fooMapper = doc.dynamicMappingsUpdate().getRoot().getMapper("field");
         assertNotNull(fooMapper);
         assertNotNull(fooMapper);
         assertThat(fooMapper, instanceOf(ObjectMapper.class));
         assertThat(fooMapper, instanceOf(ObjectMapper.class));
@@ -1364,7 +1361,7 @@ public class DocumentParserTests extends MapperServiceTestCase {
     public void testDynamicDottedFieldNameObject() throws Exception {
     public void testDynamicDottedFieldNameObject() throws Exception {
         DocumentMapper mapper = createDocumentMapper(mapping(b -> {}));
         DocumentMapper mapper = createDocumentMapper(mapping(b -> {}));
         ParsedDocument doc = mapper.parse(source(b -> b.startObject("foo.bar.baz").field("a", 0).endObject()));
         ParsedDocument doc = mapper.parse(source(b -> b.startObject("foo.bar.baz").field("a", 0).endObject()));
-        assertEquals(2, doc.rootDoc().getFields("foo.bar.baz.a").length);
+        assertEquals(1, doc.rootDoc().getFields("foo.bar.baz.a").length);
         Mapper fooMapper = doc.dynamicMappingsUpdate().getRoot().getMapper("foo");
         Mapper fooMapper = doc.dynamicMappingsUpdate().getRoot().getMapper("foo");
         assertNotNull(fooMapper);
         assertNotNull(fooMapper);
         assertThat(fooMapper, instanceOf(ObjectMapper.class));
         assertThat(fooMapper, instanceOf(ObjectMapper.class));
@@ -1399,7 +1396,7 @@ public class DocumentParserTests extends MapperServiceTestCase {
 
 
         ParsedDocument doc = mapper.parse(source(b -> b.startObject("foo.bar.baz").field("a", 0).endObject()));
         ParsedDocument doc = mapper.parse(source(b -> b.startObject("foo.bar.baz").field("a", 0).endObject()));
 
 
-        assertEquals(2, doc.rootDoc().getFields("foo.bar.baz.a").length);
+        assertEquals(1, doc.rootDoc().getFields("foo.bar.baz.a").length);
         Mapper fooMapper = doc.dynamicMappingsUpdate().getRoot().getMapper("foo");
         Mapper fooMapper = doc.dynamicMappingsUpdate().getRoot().getMapper("foo");
         assertNotNull(fooMapper);
         assertNotNull(fooMapper);
         assertThat(fooMapper, instanceOf(ObjectMapper.class));
         assertThat(fooMapper, instanceOf(ObjectMapper.class));
@@ -1417,7 +1414,7 @@ public class DocumentParserTests extends MapperServiceTestCase {
     public void testDynamicDottedFieldNameObjectWithExistingParent() throws Exception {
     public void testDynamicDottedFieldNameObjectWithExistingParent() throws Exception {
         DocumentMapper mapper = createDocumentMapper(fieldMapping(b -> b.field("type", "object")));
         DocumentMapper mapper = createDocumentMapper(fieldMapping(b -> b.field("type", "object")));
         ParsedDocument doc = mapper.parse(source(b -> b.startObject("field.bar.baz").field("a", 0).endObject()));
         ParsedDocument doc = mapper.parse(source(b -> b.startObject("field.bar.baz").field("a", 0).endObject()));
-        assertEquals(2, doc.rootDoc().getFields("field.bar.baz.a").length);
+        assertEquals(1, doc.rootDoc().getFields("field.bar.baz.a").length);
         Mapper fooMapper = doc.dynamicMappingsUpdate().getRoot().getMapper("field");
         Mapper fooMapper = doc.dynamicMappingsUpdate().getRoot().getMapper("field");
         assertNotNull(fooMapper);
         assertNotNull(fooMapper);
         assertThat(fooMapper, instanceOf(ObjectMapper.class));
         assertThat(fooMapper, instanceOf(ObjectMapper.class));
@@ -2493,9 +2490,9 @@ public class DocumentParserTests extends MapperServiceTestCase {
         assertEquals("foo.bar.baz", baz.name());
         assertEquals("foo.bar.baz", baz.name());
         assertEquals("baz", baz.simpleName());
         assertEquals("baz", baz.simpleName());
         IndexableField[] fields = doc.rootDoc().getFields("foo.bar.baz");
         IndexableField[] fields = doc.rootDoc().getFields("foo.bar.baz");
-        assertEquals(4, fields.length);
-        long[] longs = Arrays.stream(fields).mapToLong(value -> value.numericValue().longValue()).toArray();
-        assertArrayEquals(new long[] { 1, 1, 2, 2 }, longs);
+        assertEquals(2, fields.length);
+        String[] fieldStrings = Arrays.stream(fields).map(Object::toString).toArray(String[]::new);
+        assertArrayEquals(new String[] { "LongField <foo.bar.baz:1>", "LongField <foo.bar.baz:2>" }, fieldStrings);
 
 
         // merge without going through toXContent and reparsing, otherwise the potential leaf path issue gets fixed on its own
         // merge without going through toXContent and reparsing, otherwise the potential leaf path issue gets fixed on its own
         Mapping newMapping = MapperService.mergeMappings(mapperService.documentMapper(), mapping, MapperService.MergeReason.MAPPING_UPDATE);
         Mapping newMapping = MapperService.mergeMappings(mapperService.documentMapper(), mapping, MapperService.MergeReason.MAPPING_UPDATE);
@@ -2511,9 +2508,8 @@ public class DocumentParserTests extends MapperServiceTestCase {
             """));
             """));
         assertNull(doc2.dynamicMappingsUpdate());
         assertNull(doc2.dynamicMappingsUpdate());
         IndexableField[] fields2 = doc2.rootDoc().getFields("foo.bar.baz");
         IndexableField[] fields2 = doc2.rootDoc().getFields("foo.bar.baz");
-        assertEquals(2, fields2.length);
-        long[] longs2 = Arrays.stream(fields2).mapToLong(value -> value.numericValue().longValue()).toArray();
-        assertArrayEquals(new long[] { 10, 10 }, longs2);
+        assertEquals(1, fields2.length);
+        assertEquals("LongField <foo.bar.baz:10>", fields2[0].toString());
     }
     }
 
 
     public void testDeeplyNestedDocument() throws Exception {
     public void testDeeplyNestedDocument() throws Exception {

+ 3 - 5
server/src/test/java/org/elasticsearch/index/mapper/DoubleScriptMapperTests.java

@@ -72,11 +72,9 @@ public class DoubleScriptMapperTests extends MapperScriptTestCase<DoubleFieldScr
 
 
     @Override
     @Override
     protected void assertMultipleValues(IndexableField[] fields) {
     protected void assertMultipleValues(IndexableField[] fields) {
-        assertEquals(4, fields.length);
-        assertEquals("DoublePoint <field:3.14>", fields[0].toString());
-        assertEquals("docValuesType=SORTED_NUMERIC<field:4614253070214989087>", fields[1].toString());
-        assertEquals("DoublePoint <field:2.78>", fields[2].toString());
-        assertEquals("docValuesType=SORTED_NUMERIC<field:4613442422282062397>", fields[3].toString());
+        assertEquals(2, fields.length);
+        assertEquals("DoubleField <field:3.14>", fields[0].toString());
+        assertEquals("DoubleField <field:2.78>", fields[1].toString());
     }
     }
 
 
     @Override
     @Override

+ 1 - 1
server/src/test/java/org/elasticsearch/index/mapper/DynamicMappingTests.java

@@ -887,7 +887,7 @@ public class DynamicMappingTests extends MapperServiceTestCase {
             b.field("myfield", 2);
             b.field("myfield", 2);
         }));
         }));
 
 
-        assertThat(doc.rootDoc().getFields("myfield"), arrayWithSize(2));
+        assertThat(doc.rootDoc().getFields("myfield"), arrayWithSize(1));
         assertThat(doc.rootDoc().getFields("objects.subfield"), arrayWithSize(2));
         assertThat(doc.rootDoc().getFields("objects.subfield"), arrayWithSize(2));
         assertThat(doc.rootDoc().getFields("objects.unmapped"), arrayWithSize(0));
         assertThat(doc.rootDoc().getFields("objects.unmapped"), arrayWithSize(0));
         assertEquals(XContentHelper.stripWhitespace("""
         assertEquals(XContentHelper.stripWhitespace("""

+ 6 - 7
server/src/test/java/org/elasticsearch/index/mapper/IndexTimeScriptTests.java

@@ -37,9 +37,8 @@ public class IndexTimeScriptTests extends MapperServiceTestCase {
 
 
         ParsedDocument doc = mapper.parse(source(b -> b.field("message", "this is some text")));
         ParsedDocument doc = mapper.parse(source(b -> b.field("message", "this is some text")));
         IndexableField[] lengthFields = doc.rootDoc().getFields("message_length");
         IndexableField[] lengthFields = doc.rootDoc().getFields("message_length");
-        assertEquals(2, lengthFields.length);
-        assertEquals("LongPoint <message_length:17>", lengthFields[0].toString());
-        assertEquals("docValuesType=SORTED_NUMERIC<message_length:17>", lengthFields[1].toString());
+        assertEquals(1, lengthFields.length);
+        assertEquals("LongField <message_length:17>", lengthFields[0].toString());
     }
     }
 
 
     public void testDocAccess() throws IOException {
     public void testDocAccess() throws IOException {
@@ -65,7 +64,7 @@ public class IndexTimeScriptTests extends MapperServiceTestCase {
         }));
         }));
 
 
         ParsedDocument doc = mapper.parse(source(b -> b.field("double_field", 4.5)));
         ParsedDocument doc = mapper.parse(source(b -> b.field("double_field", 4.5)));
-        assertEquals(doc.rootDoc().getField("double_field_plus_two").numericValue(), 6.5);
+        assertEquals(doc.rootDoc().getField("double_field_plus_two").toString(), "DoubleField <double_field_plus_two:6.5>");
     }
     }
 
 
     public void testCrossReferences() throws IOException {
     public void testCrossReferences() throws IOException {
@@ -85,9 +84,9 @@ public class IndexTimeScriptTests extends MapperServiceTestCase {
             b.endObject();
             b.endObject();
         }));
         }));
         ParsedDocument doc = mapper.parse(source(b -> b.field("message", "this is a message")));
         ParsedDocument doc = mapper.parse(source(b -> b.field("message", "this is a message")));
-        assertEquals(doc.rootDoc().getField("message_length_plus_two").numericValue(), 19L);
-        assertEquals(doc.rootDoc().getField("message_length").numericValue(), 17L);
-        assertEquals(doc.rootDoc().getField("message_length_plus_four").numericValue(), 21d);
+        assertEquals(doc.rootDoc().getField("message_length_plus_two").toString(), "LongField <message_length_plus_two:19>");
+        assertEquals(doc.rootDoc().getField("message_length").toString(), "LongField <message_length:17>");
+        assertEquals(doc.rootDoc().getField("message_length_plus_four").toString(), "DoubleField <message_length_plus_four:21.0>");
     }
     }
 
 
     public void testLoopDetection() throws IOException {
     public void testLoopDetection() throws IOException {

+ 2 - 2
server/src/test/java/org/elasticsearch/index/mapper/LongFieldMapperTests.java

@@ -97,9 +97,9 @@ public class LongFieldMapperTests extends WholeNumberFieldMapperTests {
         // the following two strings are in-range for a long after coercion
         // the following two strings are in-range for a long after coercion
         DocumentMapper mapper = createDocumentMapper(fieldMapping(this::minimalMapping));
         DocumentMapper mapper = createDocumentMapper(fieldMapping(this::minimalMapping));
         ParsedDocument doc = mapper.parse(source(b -> b.field("field", "9223372036854775807.9")));
         ParsedDocument doc = mapper.parse(source(b -> b.field("field", "9223372036854775807.9")));
-        assertThat(doc.rootDoc().getFields("field"), arrayWithSize(2));
+        assertThat(doc.rootDoc().getFields("field"), arrayWithSize(1));
         doc = mapper.parse(source(b -> b.field("field", "-9223372036854775808.9")));
         doc = mapper.parse(source(b -> b.field("field", "-9223372036854775808.9")));
-        assertThat(doc.rootDoc().getFields("field"), arrayWithSize(2));
+        assertThat(doc.rootDoc().getFields("field"), arrayWithSize(1));
     }
     }
 
 
     @Override
     @Override

+ 3 - 5
server/src/test/java/org/elasticsearch/index/mapper/LongScriptMapperTests.java

@@ -72,11 +72,9 @@ public class LongScriptMapperTests extends MapperScriptTestCase<LongFieldScript.
 
 
     @Override
     @Override
     protected void assertMultipleValues(IndexableField[] fields) {
     protected void assertMultipleValues(IndexableField[] fields) {
-        assertEquals(4, fields.length);
-        assertEquals("LongPoint <field:1>", fields[0].toString());
-        assertEquals("docValuesType=SORTED_NUMERIC<field:1>", fields[1].toString());
-        assertEquals("LongPoint <field:2>", fields[2].toString());
-        assertEquals("docValuesType=SORTED_NUMERIC<field:2>", fields[3].toString());
+        assertEquals(2, fields.length);
+        assertEquals("LongField <field:1>", fields[0].toString());
+        assertEquals("LongField <field:2>", fields[1].toString());
     }
     }
 
 
     @Override
     @Override

+ 16 - 23
server/src/test/java/org/elasticsearch/index/mapper/NumberFieldMapperTests.java

@@ -26,6 +26,7 @@ import org.elasticsearch.xcontent.XContentBuilder;
 
 
 import java.io.IOException;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.List;
 import java.util.function.Function;
 import java.util.function.Function;
 import java.util.function.Supplier;
 import java.util.function.Supplier;
@@ -108,14 +109,10 @@ public abstract class NumberFieldMapperTests extends MapperTestCase {
         ParsedDocument doc = mapper.parse(source(b -> b.field("field", 123)));
         ParsedDocument doc = mapper.parse(source(b -> b.field("field", 123)));
 
 
         IndexableField[] fields = doc.rootDoc().getFields("field");
         IndexableField[] fields = doc.rootDoc().getFields("field");
-        assertEquals(2, fields.length);
-        IndexableField pointField = fields[0];
-        assertEquals(1, pointField.fieldType().pointIndexDimensionCount());
-        assertFalse(pointField.fieldType().stored());
-        assertEquals(123, pointField.numericValue().doubleValue(), 0d);
-        IndexableField dvField = fields[1];
-        assertEquals(DocValuesType.SORTED_NUMERIC, dvField.fieldType().docValuesType());
-        assertFalse(dvField.fieldType().stored());
+        // One field indexes points
+        assertEquals(1, Arrays.stream(fields).filter(f -> f.fieldType().pointIndexDimensionCount() != 0).count());
+        // One field indexes doc values
+        assertEquals(1, Arrays.stream(fields).filter(f -> f.fieldType().docValuesType() != DocValuesType.NONE).count());
     }
     }
 
 
     public void testNotIndexed() throws Exception {
     public void testNotIndexed() throws Exception {
@@ -153,15 +150,13 @@ public abstract class NumberFieldMapperTests extends MapperTestCase {
         ParsedDocument doc = mapper.parse(source(b -> b.field("field", 123)));
         ParsedDocument doc = mapper.parse(source(b -> b.field("field", 123)));
 
 
         IndexableField[] fields = doc.rootDoc().getFields("field");
         IndexableField[] fields = doc.rootDoc().getFields("field");
-        assertEquals(3, fields.length);
-        IndexableField pointField = fields[0];
-        assertEquals(1, pointField.fieldType().pointIndexDimensionCount());
-        assertEquals(123, pointField.numericValue().doubleValue(), 0d);
-        IndexableField dvField = fields[1];
-        assertEquals(DocValuesType.SORTED_NUMERIC, dvField.fieldType().docValuesType());
-        IndexableField storedField = fields[2];
-        assertTrue(storedField.fieldType().stored());
-        assertEquals(123, storedField.numericValue().doubleValue(), 0d);
+
+        // One field indexes points
+        assertEquals(1, Arrays.stream(fields).filter(f -> f.fieldType().pointIndexDimensionCount() != 0).count());
+        // One field indexes doc values
+        assertEquals(1, Arrays.stream(fields).filter(f -> f.fieldType().docValuesType() != DocValuesType.NONE).count());
+        // One field is stored
+        assertEquals(1, Arrays.stream(fields).filter(f -> f.fieldType().stored()).count());
     }
     }
 
 
     public void testCoerce() throws IOException {
     public void testCoerce() throws IOException {
@@ -169,12 +164,10 @@ public abstract class NumberFieldMapperTests extends MapperTestCase {
         ParsedDocument doc = mapper.parse(source(b -> b.field("field", "123")));
         ParsedDocument doc = mapper.parse(source(b -> b.field("field", "123")));
 
 
         IndexableField[] fields = doc.rootDoc().getFields("field");
         IndexableField[] fields = doc.rootDoc().getFields("field");
-        assertEquals(2, fields.length);
-        IndexableField pointField = fields[0];
-        assertEquals(1, pointField.fieldType().pointIndexDimensionCount());
-        assertEquals(123, pointField.numericValue().doubleValue(), 0d);
-        IndexableField dvField = fields[1];
-        assertEquals(DocValuesType.SORTED_NUMERIC, dvField.fieldType().docValuesType());
+        // One field indexes points
+        assertEquals(1, Arrays.stream(fields).filter(f -> f.fieldType().pointIndexDimensionCount() != 0).count());
+        // One field indexes doc values
+        assertEquals(1, Arrays.stream(fields).filter(f -> f.fieldType().docValuesType() != DocValuesType.NONE).count());
 
 
         DocumentMapper mapper2 = createDocumentMapper(fieldMapping(b -> {
         DocumentMapper mapper2 = createDocumentMapper(fieldMapping(b -> {
             minimalMapping(b);
             minimalMapping(b);

+ 1 - 1
x-pack/plugin/mapper-aggregate-metric/src/test/java/org/elasticsearch/xpack/aggregatemetric/mapper/AggregateDoubleMetricFieldMapperTests.java

@@ -110,7 +110,7 @@ public class AggregateDoubleMetricFieldMapperTests extends MapperTestCase {
         ParsedDocument doc = mapper.parse(
         ParsedDocument doc = mapper.parse(
             source(b -> b.startObject("field").field("min", -10.1).field("max", 50.0).field("value_count", 14).endObject())
             source(b -> b.startObject("field").field("min", -10.1).field("max", 50.0).field("value_count", 14).endObject())
         );
         );
-        assertEquals(-10.1, doc.rootDoc().getField("field.min").numericValue());
+        assertEquals("DoubleField <field.min:-10.1>", doc.rootDoc().getField("field.min").toString());
 
 
         Mapper fieldMapper = mapper.mappers().getMapper("field");
         Mapper fieldMapper = mapper.mappers().getMapper("field");
         assertThat(fieldMapper, instanceOf(AggregateDoubleMetricFieldMapper.class));
         assertThat(fieldMapper, instanceOf(AggregateDoubleMetricFieldMapper.class));

+ 6 - 4
x-pack/plugin/mapper-unsigned-long/src/main/java/org/elasticsearch/xpack/unsignedlong/UnsignedLongFieldMapper.java

@@ -8,6 +8,7 @@
 package org.elasticsearch.xpack.unsignedlong;
 package org.elasticsearch.xpack.unsignedlong;
 
 
 import org.apache.lucene.document.Field;
 import org.apache.lucene.document.Field;
+import org.apache.lucene.document.LongField;
 import org.apache.lucene.document.LongPoint;
 import org.apache.lucene.document.LongPoint;
 import org.apache.lucene.document.SortedNumericDocValuesField;
 import org.apache.lucene.document.SortedNumericDocValuesField;
 import org.apache.lucene.document.StoredField;
 import org.apache.lucene.document.StoredField;
@@ -605,11 +606,12 @@ public class UnsignedLongFieldMapper extends FieldMapper {
         }
         }
 
 
         List<Field> fields = new ArrayList<>();
         List<Field> fields = new ArrayList<>();
-        if (indexed) {
-            fields.add(new LongPoint(fieldType().name(), numericValue));
-        }
-        if (hasDocValues) {
+        if (indexed && hasDocValues) {
+            fields.add(new LongField(fieldType().name(), numericValue));
+        } else if (hasDocValues) {
             fields.add(new SortedNumericDocValuesField(fieldType().name(), numericValue));
             fields.add(new SortedNumericDocValuesField(fieldType().name(), numericValue));
+        } else if (indexed) {
+            fields.add(new LongPoint(fieldType().name(), numericValue));
         }
         }
         if (stored) {
         if (stored) {
             // for stored field, keeping original unsigned_long value in the String form
             // for stored field, keeping original unsigned_long value in the String form

+ 9 - 29
x-pack/plugin/mapper-unsigned-long/src/test/java/org/elasticsearch/xpack/unsignedlong/UnsignedLongFieldMapperTests.java

@@ -72,26 +72,16 @@ public class UnsignedLongFieldMapperTests extends MapperTestCase {
         {
         {
             ParsedDocument doc = mapper.parse(source(b -> b.field("field", "18446744073709551615")));
             ParsedDocument doc = mapper.parse(source(b -> b.field("field", "18446744073709551615")));
             IndexableField[] fields = doc.rootDoc().getFields("field");
             IndexableField[] fields = doc.rootDoc().getFields("field");
-            assertEquals(2, fields.length);
-            IndexableField pointField = fields[0];
-            assertEquals(1, pointField.fieldType().pointIndexDimensionCount());
-            assertFalse(pointField.fieldType().stored());
-            assertEquals(9223372036854775807L, pointField.numericValue().longValue());
-            IndexableField dvField = fields[1];
-            assertEquals(DocValuesType.SORTED_NUMERIC, dvField.fieldType().docValuesType());
-            assertEquals(9223372036854775807L, dvField.numericValue().longValue());
-            assertFalse(dvField.fieldType().stored());
+            assertEquals(1, fields.length);
+            assertEquals("LongField <field:9223372036854775807>", fields[0].toString());
         }
         }
 
 
         // test indexing values as integer numbers
         // test indexing values as integer numbers
         {
         {
             ParsedDocument doc = mapper.parse(source(b -> b.field("field", 9223372036854775807L)));
             ParsedDocument doc = mapper.parse(source(b -> b.field("field", 9223372036854775807L)));
             IndexableField[] fields = doc.rootDoc().getFields("field");
             IndexableField[] fields = doc.rootDoc().getFields("field");
-            assertEquals(2, fields.length);
-            IndexableField pointField = fields[0];
-            assertEquals(-1L, pointField.numericValue().longValue());
-            IndexableField dvField = fields[1];
-            assertEquals(-1L, dvField.numericValue().longValue());
+            assertEquals(1, fields.length);
+            assertEquals("LongField <field:-1>", fields[0].toString());
         }
         }
 
 
         // test that indexing values as number with decimal is not allowed
         // test that indexing values as number with decimal is not allowed
@@ -127,14 +117,9 @@ public class UnsignedLongFieldMapperTests extends MapperTestCase {
         DocumentMapper mapper = createDocumentMapper(fieldMapping(b -> b.field("type", "unsigned_long").field("store", true)));
         DocumentMapper mapper = createDocumentMapper(fieldMapping(b -> b.field("type", "unsigned_long").field("store", true)));
         ParsedDocument doc = mapper.parse(source(b -> b.field("field", "18446744073709551615")));
         ParsedDocument doc = mapper.parse(source(b -> b.field("field", "18446744073709551615")));
         IndexableField[] fields = doc.rootDoc().getFields("field");
         IndexableField[] fields = doc.rootDoc().getFields("field");
-        assertEquals(3, fields.length);
-        IndexableField pointField = fields[0];
-        assertEquals(1, pointField.fieldType().pointIndexDimensionCount());
-        assertEquals(9223372036854775807L, pointField.numericValue().longValue());
-        IndexableField dvField = fields[1];
-        assertEquals(DocValuesType.SORTED_NUMERIC, dvField.fieldType().docValuesType());
-        assertEquals(9223372036854775807L, dvField.numericValue().longValue());
-        IndexableField storedField = fields[2];
+        assertEquals(2, fields.length);
+        assertEquals("LongField <field:9223372036854775807>", fields[0].toString());
+        IndexableField storedField = fields[1];
         assertTrue(storedField.fieldType().stored());
         assertTrue(storedField.fieldType().stored());
         assertEquals("18446744073709551615", storedField.stringValue());
         assertEquals("18446744073709551615", storedField.stringValue());
     }
     }
@@ -166,11 +151,8 @@ public class UnsignedLongFieldMapperTests extends MapperTestCase {
             ParsedDocument doc = mapper.parse(source(b -> b.nullField("field")));
             ParsedDocument doc = mapper.parse(source(b -> b.nullField("field")));
             ;
             ;
             IndexableField[] fields = doc.rootDoc().getFields("field");
             IndexableField[] fields = doc.rootDoc().getFields("field");
-            assertEquals(2, fields.length);
-            IndexableField pointField = fields[0];
-            assertEquals(9223372036854775807L, pointField.numericValue().longValue());
-            IndexableField dvField = fields[1];
-            assertEquals(9223372036854775807L, dvField.numericValue().longValue());
+            assertEquals(1, fields.length);
+            assertEquals("LongField <field:9223372036854775807>", fields[0].toString());
         }
         }
     }
     }
 
 
@@ -202,11 +184,9 @@ public class UnsignedLongFieldMapperTests extends MapperTestCase {
         }
         }
         ParsedDocument doc = mapper.parse(source(b -> b.field("field", randomFrom("100.", "100.0", "100.00", 100.0, 100.0f))));
         ParsedDocument doc = mapper.parse(source(b -> b.field("field", randomFrom("100.", "100.0", "100.00", 100.0, 100.0f))));
         assertThat(doc.rootDoc().getFields("field")[0].numericValue().longValue(), equalTo(Long.MIN_VALUE + 100L));
         assertThat(doc.rootDoc().getFields("field")[0].numericValue().longValue(), equalTo(Long.MIN_VALUE + 100L));
-        assertThat(doc.rootDoc().getFields("field")[1].numericValue().longValue(), equalTo(Long.MIN_VALUE + 100L));
 
 
         doc = mapper.parse(source(b -> b.field("field", randomFrom("0.", "0.0", ".00", 0.0, 0.0f))));
         doc = mapper.parse(source(b -> b.field("field", randomFrom("0.", "0.0", ".00", 0.0, 0.0f))));
         assertThat(doc.rootDoc().getFields("field")[0].numericValue().longValue(), equalTo(Long.MIN_VALUE));
         assertThat(doc.rootDoc().getFields("field")[0].numericValue().longValue(), equalTo(Long.MIN_VALUE));
-        assertThat(doc.rootDoc().getFields("field")[1].numericValue().longValue(), equalTo(Long.MIN_VALUE));
     }
     }
 
 
     public void testIndexingOutOfRangeValues() throws Exception {
     public void testIndexingOutOfRangeValues() throws Exception {