Mappings: Bring back numeric_resolution.
We had an undocumented parameter called `numeric_resolution` which allows to configure how to deal with dates when provided as a number. The default is to handle them as milliseconds, but you can also opt-on for eg. seconds. Close #10072
This commit is contained in:
parent
3f8908acfb
commit
c7115f8364
|
@ -378,6 +378,9 @@ defaults to `true` or to the parent `object` type setting.
|
||||||
|
|
||||||
|`ignore_malformed` |Ignored a malformed number. Defaults to `false`.
|
|`ignore_malformed` |Ignored a malformed number. Defaults to `false`.
|
||||||
|
|
||||||
|
|`numeric_resolution` |The unit to use when passed in a numeric values. Possible
|
||||||
|
values include `seconds` and `milliseconds` (default).
|
||||||
|
|
||||||
|=======================================================================
|
|=======================================================================
|
||||||
|
|
||||||
[float]
|
[float]
|
||||||
|
|
|
@ -488,13 +488,14 @@ public class DateFieldMapper extends NumberFieldMapper<Long> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
|
final long timestamp = timeUnit.toMillis(value);
|
||||||
if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored()) {
|
if (fieldType.indexOptions() != IndexOptions.NONE || fieldType.stored()) {
|
||||||
CustomLongNumericField field = new CustomLongNumericField(this, value, fieldType);
|
CustomLongNumericField field = new CustomLongNumericField(this, timestamp, fieldType);
|
||||||
field.setBoost(boost);
|
field.setBoost(boost);
|
||||||
fields.add(field);
|
fields.add(field);
|
||||||
}
|
}
|
||||||
if (hasDocValues()) {
|
if (hasDocValues()) {
|
||||||
addDocValue(context, fields, value);
|
addDocValue(context, fields, timestamp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -553,8 +554,7 @@ public class DateFieldMapper extends NumberFieldMapper<Long> {
|
||||||
return dateTimeFormatter.parser().parseMillis(value);
|
return dateTimeFormatter.parser().parseMillis(value);
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
try {
|
try {
|
||||||
long time = Long.parseLong(value);
|
return Long.parseLong(value);
|
||||||
return timeUnit.toMillis(time);
|
|
||||||
} catch (NumberFormatException e1) {
|
} catch (NumberFormatException e1) {
|
||||||
throw new MapperParsingException("failed to parse date field [" + value + "], tried both date format [" + dateTimeFormatter.format() + "], and timestamp number with locale [" + dateTimeFormatter.locale() + "]", e);
|
throw new MapperParsingException("failed to parse date field [" + value + "], tried both date format [" + dateTimeFormatter.format() + "], and timestamp number with locale [" + dateTimeFormatter.locale() + "]", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ package org.elasticsearch.index.mapper.date;
|
||||||
import org.apache.lucene.analysis.NumericTokenStream.NumericTermAttribute;
|
import org.apache.lucene.analysis.NumericTokenStream.NumericTermAttribute;
|
||||||
import org.apache.lucene.analysis.TokenStream;
|
import org.apache.lucene.analysis.TokenStream;
|
||||||
import org.apache.lucene.index.DocValuesType;
|
import org.apache.lucene.index.DocValuesType;
|
||||||
|
import org.apache.lucene.index.IndexableField;
|
||||||
import org.apache.lucene.search.Filter;
|
import org.apache.lucene.search.Filter;
|
||||||
import org.apache.lucene.search.NumericRangeFilter;
|
import org.apache.lucene.search.NumericRangeFilter;
|
||||||
import org.elasticsearch.ElasticsearchIllegalArgumentException;
|
import org.elasticsearch.ElasticsearchIllegalArgumentException;
|
||||||
|
@ -38,10 +39,12 @@ import org.elasticsearch.index.mapper.DocumentMapperParser;
|
||||||
import org.elasticsearch.index.mapper.FieldMapper;
|
import org.elasticsearch.index.mapper.FieldMapper;
|
||||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||||
import org.elasticsearch.index.mapper.ParseContext;
|
import org.elasticsearch.index.mapper.ParseContext;
|
||||||
|
import org.elasticsearch.index.mapper.ParseContext.Document;
|
||||||
import org.elasticsearch.index.mapper.ParsedDocument;
|
import org.elasticsearch.index.mapper.ParsedDocument;
|
||||||
import org.elasticsearch.index.mapper.core.DateFieldMapper;
|
import org.elasticsearch.index.mapper.core.DateFieldMapper;
|
||||||
import org.elasticsearch.index.mapper.core.LongFieldMapper;
|
import org.elasticsearch.index.mapper.core.LongFieldMapper;
|
||||||
import org.elasticsearch.index.mapper.core.StringFieldMapper;
|
import org.elasticsearch.index.mapper.core.StringFieldMapper;
|
||||||
|
import org.elasticsearch.search.aggregations.support.ValuesSource.Numeric;
|
||||||
import org.elasticsearch.search.internal.SearchContext;
|
import org.elasticsearch.search.internal.SearchContext;
|
||||||
import org.elasticsearch.test.ElasticsearchSingleNodeTest;
|
import org.elasticsearch.test.ElasticsearchSingleNodeTest;
|
||||||
import org.elasticsearch.test.TestSearchContext;
|
import org.elasticsearch.test.TestSearchContext;
|
||||||
|
@ -55,8 +58,8 @@ import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.elasticsearch.index.mapper.string.SimpleStringMappingTests.docValuesType;
|
|
||||||
import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
|
import static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;
|
||||||
|
import static org.elasticsearch.index.mapper.string.SimpleStringMappingTests.docValuesType;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.hasKey;
|
import static org.hamcrest.Matchers.hasKey;
|
||||||
import static org.hamcrest.Matchers.instanceOf;
|
import static org.hamcrest.Matchers.instanceOf;
|
||||||
|
@ -396,4 +399,37 @@ public class SimpleDateMappingTests extends ElasticsearchSingleNodeTest {
|
||||||
assertThat(dateFieldMapperMap.get("field"), is(instanceOf(Map.class)));
|
assertThat(dateFieldMapperMap.get("field"), is(instanceOf(Map.class)));
|
||||||
return (Map<String, String>) dateFieldMapperMap.get("field");
|
return (Map<String, String>) dateFieldMapperMap.get("field");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static long getDateAsMillis(Document doc, String field) {
|
||||||
|
for (IndexableField f : doc.getFields(field)) {
|
||||||
|
if (f.numericValue() != null) {
|
||||||
|
return f.numericValue().longValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new AssertionError("missing");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNumericResolution() throws Exception {
|
||||||
|
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type")
|
||||||
|
.startObject("properties").startObject("date_field").field("type", "date").field("format", "date_time").field("numeric_resolution", "seconds").endObject().endObject()
|
||||||
|
.endObject().endObject().string();
|
||||||
|
|
||||||
|
DocumentMapper defaultMapper = mapper(mapping);
|
||||||
|
|
||||||
|
// provided as an int
|
||||||
|
ParsedDocument doc = defaultMapper.parse("type", "1", XContentFactory.jsonBuilder()
|
||||||
|
.startObject()
|
||||||
|
.field("date_field", 42)
|
||||||
|
.endObject()
|
||||||
|
.bytes());
|
||||||
|
assertThat(getDateAsMillis(doc.rootDoc(), "date_field"), equalTo(42000L));
|
||||||
|
|
||||||
|
// provided as a string
|
||||||
|
doc = defaultMapper.parse("type", "2", XContentFactory.jsonBuilder()
|
||||||
|
.startObject()
|
||||||
|
.field("date_field", "43")
|
||||||
|
.endObject()
|
||||||
|
.bytes());
|
||||||
|
assertThat(getDateAsMillis(doc.rootDoc(), "date_field"), equalTo(43000L));
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue