org.elasticsearch.index.mapper.DateFieldMapper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of elasticsearch Show documentation
Show all versions of elasticsearch Show documentation
Elasticsearch subproject :distribution:archives:integ-test-zip
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
package org.elasticsearch.index.mapper;
import org.apache.lucene.document.LongPoint;
import org.apache.lucene.document.SortedNumericDocValuesField;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.PointValues;
import org.apache.lucene.search.BoostQuery;
import org.apache.lucene.search.IndexOrDocValuesQuery;
import org.apache.lucene.search.IndexSortSortedNumericDocValuesRangeQuery;
import org.apache.lucene.search.Query;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.Version;
import org.elasticsearch.common.geo.ShapeRelation;
import org.elasticsearch.common.joda.Joda;
import org.elasticsearch.common.logging.DeprecationCategory;
import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.common.lucene.BytesRefs;
import org.elasticsearch.common.time.DateFormatter;
import org.elasticsearch.common.time.DateFormatters;
import org.elasticsearch.common.time.DateMathParser;
import org.elasticsearch.common.time.DateUtils;
import org.elasticsearch.common.util.LocaleUtils;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.index.fielddata.IndexFieldData;
import org.elasticsearch.index.fielddata.IndexNumericFieldData.NumericType;
import org.elasticsearch.index.fielddata.plain.SortedNumericIndexFieldData;
import org.elasticsearch.index.query.DateRangeIncludingNowQuery;
import org.elasticsearch.index.query.QueryRewriteContext;
import org.elasticsearch.index.query.SearchExecutionContext;
import org.elasticsearch.script.DateFieldScript;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptCompiler;
import org.elasticsearch.search.DocValueFormat;
import org.elasticsearch.search.lookup.FieldValues;
import org.elasticsearch.search.lookup.SearchLookup;
import java.io.IOException;
import java.text.NumberFormat;
import java.time.DateTimeException;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.LongSupplier;
import java.util.function.Supplier;
import static org.elasticsearch.common.time.DateUtils.toLong;
/** A {@link FieldMapper} for dates. */
public final class DateFieldMapper extends FieldMapper {
private static final DeprecationLogger DEPRECATION_LOGGER = DeprecationLogger.getLogger(DateFieldMapper.class);
public static final String CONTENT_TYPE = "date";
public static final String DATE_NANOS_CONTENT_TYPE = "date_nanos";
public static final DateFormatter DEFAULT_DATE_TIME_FORMATTER = DateFormatter.forPattern("strict_date_optional_time||epoch_millis");
public static final DateFormatter DEFAULT_DATE_TIME_NANOS_FORMATTER = DateFormatter.forPattern(
"strict_date_optional_time_nanos||epoch_millis"
);
public enum Resolution {
MILLISECONDS(CONTENT_TYPE, NumericType.DATE) {
@Override
public long convert(Instant instant) {
return instant.toEpochMilli();
}
@Override
public Instant toInstant(long value) {
return Instant.ofEpochMilli(value);
}
@Override
public Instant clampToValidRange(Instant instant) {
return instant;
}
@Override
public long parsePointAsMillis(byte[] value) {
return LongPoint.decodeDimension(value, 0);
}
@Override
public long roundDownToMillis(long value) {
return value;
}
@Override
public long roundUpToMillis(long value) {
return value;
}
@Override
protected Query distanceFeatureQuery(String field, float boost, long origin, TimeValue pivot) {
return LongPoint.newDistanceFeatureQuery(field, boost, origin, pivot.getMillis());
}
},
NANOSECONDS(DATE_NANOS_CONTENT_TYPE, NumericType.DATE_NANOSECONDS) {
@Override
public long convert(Instant instant) {
return toLong(instant);
}
@Override
public Instant toInstant(long value) {
return DateUtils.toInstant(value);
}
@Override
public Instant clampToValidRange(Instant instant) {
return DateUtils.clampToNanosRange(instant);
}
@Override
public long parsePointAsMillis(byte[] value) {
return roundDownToMillis(LongPoint.decodeDimension(value, 0));
}
@Override
public long roundDownToMillis(long value) {
return DateUtils.toMilliSeconds(value);
}
@Override
public long roundUpToMillis(long value) {
if (value <= 0L) {
// if negative then throws an IAE; if zero then return zero
return DateUtils.toMilliSeconds(value);
} else {
return DateUtils.toMilliSeconds(value - 1L) + 1L;
}
}
@Override
protected Query distanceFeatureQuery(String field, float boost, long origin, TimeValue pivot) {
return LongPoint.newDistanceFeatureQuery(field, boost, origin, pivot.getNanos());
}
};
private final String type;
private final NumericType numericType;
Resolution(String type, NumericType numericType) {
this.type = type;
this.numericType = numericType;
}
public String type() {
return type;
}
NumericType numericType() {
return numericType;
}
/**
* Convert an {@linkplain Instant} into a long value in this resolution.
*/
public abstract long convert(Instant instant);
/**
* Convert a long value in this resolution into an instant.
*/
public abstract Instant toInstant(long value);
/**
* Return the instant that this range can represent that is closest to
* the provided instant.
*/
public abstract Instant clampToValidRange(Instant instant);
/**
* Decode the points representation of this field as milliseconds.
*/
public abstract long parsePointAsMillis(byte[] value);
/**
* Round the given raw value down to a number of milliseconds since the epoch.
*/
public abstract long roundDownToMillis(long value);
/**
* Round the given raw value up to a number of milliseconds since the epoch.
*/
public abstract long roundUpToMillis(long value);
public static Resolution ofOrdinal(int ord) {
for (Resolution resolution : values()) {
if (ord == resolution.ordinal()) {
return resolution;
}
}
throw new IllegalArgumentException("unknown resolution ordinal [" + ord + "]");
}
protected abstract Query distanceFeatureQuery(String field, float boost, long origin, TimeValue pivot);
}
private static DateFieldMapper toType(FieldMapper in) {
return (DateFieldMapper) in;
}
public static class Builder extends FieldMapper.Builder {
private final Parameter index = Parameter.indexParam(m -> toType(m).indexed, true);
private final Parameter docValues = Parameter.docValuesParam(m -> toType(m).hasDocValues, true);
private final Parameter store = Parameter.storeParam(m -> toType(m).store, false);
private final Parameter boost = Parameter.boostParam();
private final Parameter