Previously we'd get a `ClassCastException` when you tried to use `numeric_type` on `scaled_float`. Oops! This cleans up the CCE and moves some code around so the casting actually works.
This commit is contained in:
parent
07c76f2894
commit
f52e779806
|
@ -29,14 +29,11 @@ import org.apache.lucene.index.Term;
|
|||
import org.apache.lucene.search.BoostQuery;
|
||||
import org.apache.lucene.search.DocValuesFieldExistsQuery;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.SortField;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
import org.elasticsearch.common.Explicit;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.settings.Setting;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.util.BigArrays;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.common.xcontent.XContentParser.Token;
|
||||
|
@ -45,7 +42,6 @@ import org.elasticsearch.index.Index;
|
|||
import org.elasticsearch.index.IndexSettings;
|
||||
import org.elasticsearch.index.fielddata.FieldData;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldDataCache;
|
||||
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
||||
import org.elasticsearch.index.fielddata.LeafNumericFieldData;
|
||||
|
@ -53,17 +49,13 @@ import org.elasticsearch.index.fielddata.NumericDoubleValues;
|
|||
import org.elasticsearch.index.fielddata.ScriptDocValues;
|
||||
import org.elasticsearch.index.fielddata.SortedBinaryDocValues;
|
||||
import org.elasticsearch.index.fielddata.SortedNumericDoubleValues;
|
||||
import org.elasticsearch.index.fielddata.fieldcomparator.DoubleValuesComparatorSource;
|
||||
import org.elasticsearch.index.fielddata.plain.SortedNumericIndexFieldData;
|
||||
import org.elasticsearch.index.mapper.NumberFieldMapper.Defaults;
|
||||
import org.elasticsearch.index.query.QueryShardContext;
|
||||
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
||||
import org.elasticsearch.search.DocValueFormat;
|
||||
import org.elasticsearch.search.MultiValueMode;
|
||||
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
|
||||
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
|
||||
import org.elasticsearch.search.sort.BucketedSort;
|
||||
import org.elasticsearch.search.sort.SortOrder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
|
@ -499,7 +491,7 @@ public class ScaledFloatFieldMapper extends FieldMapper {
|
|||
return doubleValue;
|
||||
}
|
||||
|
||||
private static class ScaledFloatIndexFieldData implements IndexNumericFieldData {
|
||||
private static class ScaledFloatIndexFieldData extends IndexNumericFieldData {
|
||||
|
||||
private final IndexNumericFieldData scaledFieldData;
|
||||
private final double scalingFactor;
|
||||
|
@ -525,16 +517,15 @@ public class ScaledFloatFieldMapper extends FieldMapper {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SortField sortField(@Nullable Object missingValue, MultiValueMode sortMode, Nested nested, boolean reverse) {
|
||||
final XFieldComparatorSource source = new DoubleValuesComparatorSource(this, missingValue, sortMode, nested);
|
||||
return new SortField(getFieldName(), source, reverse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BucketedSort newBucketedSort(BigArrays bigArrays, Object missingValue, MultiValueMode sortMode, Nested nested,
|
||||
SortOrder sortOrder, DocValueFormat format, int bucketSize, BucketedSort.ExtraData extra) {
|
||||
return new DoubleValuesComparatorSource(this, missingValue, sortMode, nested)
|
||||
.newBucketedSort(bigArrays, sortOrder, format, bucketSize, extra);
|
||||
protected boolean sortRequiresCustomComparator() {
|
||||
/*
|
||||
* We need to use a custom comparator because the non-custom
|
||||
* comparator wouldn't properly decode the long bits into the
|
||||
* double. Sorting on the long representation *would* put the
|
||||
* docs in order. We just don't have a way to convert the long
|
||||
* into a double the right way afterwords.
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -549,7 +540,7 @@ public class ScaledFloatFieldMapper extends FieldMapper {
|
|||
|
||||
@Override
|
||||
public NumericType getNumericType() {
|
||||
/**
|
||||
/*
|
||||
* {@link ScaledFloatLeafFieldData#getDoubleValues()} transforms the raw long values in `scaled` floats.
|
||||
*/
|
||||
return NumericType.DOUBLE;
|
||||
|
|
|
@ -97,8 +97,28 @@ setup:
|
|||
|
||||
- do:
|
||||
search:
|
||||
rest_total_hits_as_int: true
|
||||
body: { "size" : 1, "sort" : { "number" : { "order" : "asc" } } }
|
||||
body:
|
||||
size: 1
|
||||
sort:
|
||||
number:
|
||||
order: asc
|
||||
|
||||
- match: { hits.total: 4 }
|
||||
- match: { hits.total.value: 4 }
|
||||
- match: { hits.hits.0._id: "3" }
|
||||
- match: { hits.hits.0.sort.0: -2.1 }
|
||||
|
||||
---
|
||||
"Sort with numeric_type":
|
||||
|
||||
- do:
|
||||
search:
|
||||
body:
|
||||
size: 1
|
||||
sort:
|
||||
number:
|
||||
order: asc
|
||||
numeric_type: long
|
||||
|
||||
- match: { hits.total.value: 4 }
|
||||
- match: { hits.hits.0._id: "3" }
|
||||
- match: { hits.hits.0.sort.0: -2 }
|
||||
|
|
|
@ -19,31 +19,184 @@
|
|||
|
||||
package org.elasticsearch.index.fielddata;
|
||||
|
||||
public interface IndexNumericFieldData extends IndexFieldData<LeafNumericFieldData> {
|
||||
import org.apache.lucene.index.SortedNumericDocValues;
|
||||
import org.apache.lucene.search.SortField;
|
||||
import org.apache.lucene.search.SortedNumericSelector;
|
||||
import org.apache.lucene.search.SortedNumericSortField;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.time.DateUtils;
|
||||
import org.elasticsearch.common.util.BigArrays;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
||||
import org.elasticsearch.index.fielddata.fieldcomparator.DoubleValuesComparatorSource;
|
||||
import org.elasticsearch.index.fielddata.fieldcomparator.FloatValuesComparatorSource;
|
||||
import org.elasticsearch.index.fielddata.fieldcomparator.LongValuesComparatorSource;
|
||||
import org.elasticsearch.search.DocValueFormat;
|
||||
import org.elasticsearch.search.MultiValueMode;
|
||||
import org.elasticsearch.search.sort.BucketedSort;
|
||||
import org.elasticsearch.search.sort.SortOrder;
|
||||
|
||||
enum NumericType {
|
||||
BOOLEAN(false),
|
||||
BYTE(false),
|
||||
SHORT(false),
|
||||
INT(false),
|
||||
LONG(false),
|
||||
DATE(false),
|
||||
DATE_NANOSECONDS(false),
|
||||
HALF_FLOAT(true),
|
||||
FLOAT(true),
|
||||
DOUBLE(true);
|
||||
import java.io.IOException;
|
||||
import java.util.function.LongUnaryOperator;
|
||||
|
||||
/**
|
||||
* Base class for numeric field data.
|
||||
*/
|
||||
public abstract class IndexNumericFieldData implements IndexFieldData<LeafNumericFieldData> {
|
||||
/**
|
||||
* The type of number.
|
||||
*/
|
||||
public enum NumericType {
|
||||
BOOLEAN(false, SortField.Type.LONG),
|
||||
BYTE(false, SortField.Type.LONG),
|
||||
SHORT(false, SortField.Type.LONG),
|
||||
INT(false, SortField.Type.LONG),
|
||||
LONG(false, SortField.Type.LONG),
|
||||
DATE(false, SortField.Type.LONG),
|
||||
DATE_NANOSECONDS(false, SortField.Type.LONG),
|
||||
HALF_FLOAT(true, SortField.Type.LONG),
|
||||
FLOAT(true, SortField.Type.FLOAT),
|
||||
DOUBLE(true, SortField.Type.DOUBLE);
|
||||
|
||||
private final boolean floatingPoint;
|
||||
private final SortField.Type sortFieldType;
|
||||
|
||||
NumericType(boolean floatingPoint) {
|
||||
NumericType(boolean floatingPoint, SortField.Type sortFieldType) {
|
||||
this.floatingPoint = floatingPoint;
|
||||
this.sortFieldType = sortFieldType;
|
||||
}
|
||||
|
||||
public final boolean isFloatingPoint() {
|
||||
return floatingPoint;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NumericType getNumericType();
|
||||
/**
|
||||
* The numeric type of this number.
|
||||
*/
|
||||
public abstract NumericType getNumericType();
|
||||
|
||||
/**
|
||||
* Returns the {@link SortField} to used for sorting.
|
||||
* Values are casted to the provided <code>targetNumericType</code> type if it doesn't
|
||||
* match the field's <code>numericType</code>.
|
||||
*/
|
||||
public final SortField sortField(
|
||||
NumericType targetNumericType,
|
||||
Object missingValue,
|
||||
MultiValueMode sortMode,
|
||||
Nested nested,
|
||||
boolean reverse
|
||||
) {
|
||||
XFieldComparatorSource source = comparatorSource(targetNumericType, missingValue, sortMode, nested);
|
||||
|
||||
/*
|
||||
* Use a SortField with the custom comparator logic if required because
|
||||
* 1. The underlying data source needs it.
|
||||
* 2. We need to read the value from a nested field.
|
||||
* 3. We Aren't using max or min to resolve the duplicates.
|
||||
* 4. We have to cast the results to another type.
|
||||
*/
|
||||
if (sortRequiresCustomComparator()
|
||||
|| nested != null
|
||||
|| (sortMode != MultiValueMode.MAX && sortMode != MultiValueMode.MIN)
|
||||
|| targetNumericType != getNumericType()) {
|
||||
return new SortField(getFieldName(), source, reverse);
|
||||
}
|
||||
|
||||
SortedNumericSelector.Type selectorType = sortMode == MultiValueMode.MAX ?
|
||||
SortedNumericSelector.Type.MAX : SortedNumericSelector.Type.MIN;
|
||||
SortField sortField = new SortedNumericSortField(getFieldName(), getNumericType().sortFieldType, reverse, selectorType);
|
||||
sortField.setMissingValue(source.missingObject(missingValue, reverse));
|
||||
return sortField;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does {@link #sortField} require a custom comparator because of the way
|
||||
* the data is stored in doc values ({@code true}) or are the docs values
|
||||
* stored such that they can be sorted without decoding ({@code false}).
|
||||
*/
|
||||
protected abstract boolean sortRequiresCustomComparator();
|
||||
|
||||
@Override
|
||||
public final SortField sortField(Object missingValue, MultiValueMode sortMode, Nested nested, boolean reverse) {
|
||||
return sortField(getNumericType(), missingValue, sortMode, nested, reverse);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a {@linkplain BucketedSort} for the {@code targetNumericType},
|
||||
* casting the values if their native type doesn't match.
|
||||
*/
|
||||
public final BucketedSort newBucketedSort(NumericType targetNumericType, BigArrays bigArrays, @Nullable Object missingValue,
|
||||
MultiValueMode sortMode, Nested nested, SortOrder sortOrder, DocValueFormat format,
|
||||
int bucketSize, BucketedSort.ExtraData extra) {
|
||||
return comparatorSource(targetNumericType, missingValue, sortMode, nested)
|
||||
.newBucketedSort(bigArrays, sortOrder, format, bucketSize, extra);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final BucketedSort newBucketedSort(BigArrays bigArrays, @Nullable Object missingValue, MultiValueMode sortMode, Nested nested,
|
||||
SortOrder sortOrder, DocValueFormat format, int bucketSize, BucketedSort.ExtraData extra) {
|
||||
return newBucketedSort(getNumericType(), bigArrays, missingValue, sortMode, nested, sortOrder, format, bucketSize, extra);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a {@link XFieldComparatorSource} matching the parameters.
|
||||
*/
|
||||
private XFieldComparatorSource comparatorSource(
|
||||
NumericType targetNumericType,
|
||||
@Nullable Object missingValue,
|
||||
MultiValueMode sortMode,
|
||||
Nested nested
|
||||
) {
|
||||
switch (targetNumericType) {
|
||||
case HALF_FLOAT:
|
||||
case FLOAT:
|
||||
return new FloatValuesComparatorSource(this, missingValue, sortMode, nested);
|
||||
case DOUBLE:
|
||||
return new DoubleValuesComparatorSource(this, missingValue, sortMode, nested);
|
||||
case DATE:
|
||||
return dateComparatorSource(missingValue, sortMode, nested);
|
||||
case DATE_NANOSECONDS:
|
||||
return dateNanosComparatorSource(missingValue, sortMode, nested);
|
||||
default:
|
||||
assert !targetNumericType.isFloatingPoint();
|
||||
return new LongValuesComparatorSource(this, missingValue, sortMode, nested);
|
||||
}
|
||||
}
|
||||
|
||||
protected XFieldComparatorSource dateComparatorSource(@Nullable Object missingValue, MultiValueMode sortMode, Nested nested) {
|
||||
return new LongValuesComparatorSource(this, missingValue, sortMode, nested);
|
||||
}
|
||||
|
||||
protected XFieldComparatorSource dateNanosComparatorSource(@Nullable Object missingValue, MultiValueMode sortMode, Nested nested) {
|
||||
return new LongValuesComparatorSource(this, missingValue, sortMode, nested, dvs -> convertNumeric(dvs, DateUtils::toNanoSeconds));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the values in <code>dvs</code> using the provided <code>converter</code>.
|
||||
*/
|
||||
protected static SortedNumericDocValues convertNumeric(SortedNumericDocValues values, LongUnaryOperator converter) {
|
||||
return new AbstractSortedNumericDocValues() {
|
||||
|
||||
@Override
|
||||
public boolean advanceExact(int target) throws IOException {
|
||||
return values.advanceExact(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long nextValue() throws IOException {
|
||||
return converter.applyAsLong(values.nextValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int docValueCount() {
|
||||
return values.docValueCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextDoc() throws IOException {
|
||||
return values.nextDoc();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,17 +26,11 @@ import org.apache.lucene.index.LeafReader;
|
|||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.index.NumericDocValues;
|
||||
import org.apache.lucene.index.SortedNumericDocValues;
|
||||
import org.apache.lucene.search.SortField;
|
||||
import org.apache.lucene.search.SortedNumericSelector;
|
||||
import org.apache.lucene.search.SortedNumericSortField;
|
||||
import org.apache.lucene.util.Accountable;
|
||||
import org.apache.lucene.util.NumericUtils;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.time.DateUtils;
|
||||
import org.elasticsearch.common.util.BigArrays;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.IndexSettings;
|
||||
import org.elasticsearch.index.fielddata.AbstractSortedNumericDocValues;
|
||||
import org.elasticsearch.index.fielddata.FieldData;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
||||
|
@ -45,28 +39,22 @@ import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
|||
import org.elasticsearch.index.fielddata.LeafNumericFieldData;
|
||||
import org.elasticsearch.index.fielddata.NumericDoubleValues;
|
||||
import org.elasticsearch.index.fielddata.SortedNumericDoubleValues;
|
||||
import org.elasticsearch.index.fielddata.fieldcomparator.DoubleValuesComparatorSource;
|
||||
import org.elasticsearch.index.fielddata.fieldcomparator.FloatValuesComparatorSource;
|
||||
import org.elasticsearch.index.fielddata.fieldcomparator.LongValuesComparatorSource;
|
||||
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
import org.elasticsearch.indices.breaker.CircuitBreakerService;
|
||||
import org.elasticsearch.search.DocValueFormat;
|
||||
import org.elasticsearch.search.MultiValueMode;
|
||||
import org.elasticsearch.search.sort.BucketedSort;
|
||||
import org.elasticsearch.search.sort.SortOrder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
import java.util.function.LongUnaryOperator;
|
||||
|
||||
/**
|
||||
* FieldData backed by {@link LeafReader#getSortedNumericDocValues(String)}
|
||||
* @see DocValuesType#SORTED_NUMERIC
|
||||
*/
|
||||
public class SortedNumericIndexFieldData implements IndexNumericFieldData {
|
||||
public class SortedNumericIndexFieldData extends IndexNumericFieldData {
|
||||
public static class Builder implements IndexFieldData.Builder {
|
||||
|
||||
private final NumericType numericType;
|
||||
|
@ -113,95 +101,29 @@ public class SortedNumericIndexFieldData implements IndexNumericFieldData {
|
|||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link SortField} to used for sorting.
|
||||
* Values are casted to the provided <code>targetNumericType</code> type if it doesn't
|
||||
* match the field's <code>numericType</code>.
|
||||
*/
|
||||
public SortField sortField(NumericType targetNumericType, Object missingValue, MultiValueMode sortMode,
|
||||
Nested nested, boolean reverse) {
|
||||
final XFieldComparatorSource source = comparatorSource(targetNumericType, missingValue, sortMode, nested);
|
||||
|
||||
/**
|
||||
* Check if we can use a simple {@link SortedNumericSortField} compatible with index sorting and
|
||||
* returns a custom sort field otherwise.
|
||||
*/
|
||||
if (nested != null
|
||||
|| (sortMode != MultiValueMode.MAX && sortMode != MultiValueMode.MIN)
|
||||
|| numericType == NumericType.HALF_FLOAT
|
||||
|| targetNumericType != numericType) {
|
||||
return new SortField(fieldName, source, reverse);
|
||||
}
|
||||
|
||||
final SortField sortField;
|
||||
final SortedNumericSelector.Type selectorType = sortMode == MultiValueMode.MAX ?
|
||||
SortedNumericSelector.Type.MAX : SortedNumericSelector.Type.MIN;
|
||||
switch (numericType) {
|
||||
case FLOAT:
|
||||
sortField = new SortedNumericSortField(fieldName, SortField.Type.FLOAT, reverse, selectorType);
|
||||
break;
|
||||
|
||||
case DOUBLE:
|
||||
sortField = new SortedNumericSortField(fieldName, SortField.Type.DOUBLE, reverse, selectorType);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert !numericType.isFloatingPoint();
|
||||
sortField = new SortedNumericSortField(fieldName, SortField.Type.LONG, reverse, selectorType);
|
||||
break;
|
||||
}
|
||||
sortField.setMissingValue(source.missingObject(missingValue, reverse));
|
||||
return sortField;
|
||||
@Override
|
||||
protected boolean sortRequiresCustomComparator() {
|
||||
return numericType == NumericType.HALF_FLOAT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SortField sortField(Object missingValue, MultiValueMode sortMode, Nested nested, boolean reverse) {
|
||||
return sortField(numericType, missingValue, sortMode, nested, reverse);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a {@linkplain BucketedSort} for the {@code targetNumericType},
|
||||
* casting the values if their native type doesn't match.
|
||||
*/
|
||||
public BucketedSort newBucketedSort(NumericType targetNumericType, BigArrays bigArrays, @Nullable Object missingValue,
|
||||
MultiValueMode sortMode, Nested nested, SortOrder sortOrder, DocValueFormat format,
|
||||
int bucketSize, BucketedSort.ExtraData extra) {
|
||||
return comparatorSource(targetNumericType, missingValue, sortMode, nested)
|
||||
.newBucketedSort(bigArrays, sortOrder, format, bucketSize, extra);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BucketedSort newBucketedSort(BigArrays bigArrays, @Nullable Object missingValue, MultiValueMode sortMode, Nested nested,
|
||||
SortOrder sortOrder, DocValueFormat format, int bucketSize, BucketedSort.ExtraData extra) {
|
||||
return newBucketedSort(numericType, bigArrays, missingValue, sortMode, nested, sortOrder, format, bucketSize, extra);
|
||||
}
|
||||
|
||||
private XFieldComparatorSource comparatorSource(NumericType targetNumericType, @Nullable Object missingValue, MultiValueMode sortMode,
|
||||
Nested nested) {
|
||||
switch (targetNumericType) {
|
||||
case HALF_FLOAT:
|
||||
case FLOAT:
|
||||
return new FloatValuesComparatorSource(this, missingValue, sortMode, nested);
|
||||
case DOUBLE:
|
||||
return new DoubleValuesComparatorSource(this, missingValue, sortMode, nested);
|
||||
case DATE:
|
||||
if (numericType == NumericType.DATE_NANOSECONDS) {
|
||||
// converts date values to nanosecond resolution
|
||||
return new LongValuesComparatorSource(this, missingValue,
|
||||
sortMode, nested, dvs -> convertNanosToMillis(dvs));
|
||||
}
|
||||
return new LongValuesComparatorSource(this, missingValue, sortMode, nested);
|
||||
case DATE_NANOSECONDS:
|
||||
if (numericType == NumericType.DATE) {
|
||||
// converts date_nanos values to millisecond resolution
|
||||
return new LongValuesComparatorSource(this, missingValue,
|
||||
sortMode, nested, dvs -> convertMillisToNanos(dvs));
|
||||
}
|
||||
return new LongValuesComparatorSource(this, missingValue, sortMode, nested);
|
||||
default:
|
||||
assert !targetNumericType.isFloatingPoint();
|
||||
return new LongValuesComparatorSource(this, missingValue, sortMode, nested);
|
||||
protected XFieldComparatorSource dateComparatorSource(Object missingValue, MultiValueMode sortMode, Nested nested) {
|
||||
if (numericType == NumericType.DATE_NANOSECONDS) {
|
||||
// converts date values to nanosecond resolution
|
||||
return new LongValuesComparatorSource(this, missingValue,
|
||||
sortMode, nested, dvs -> convertNumeric(dvs, DateUtils::toMilliSeconds));
|
||||
}
|
||||
return new LongValuesComparatorSource(this, missingValue, sortMode, nested);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected XFieldComparatorSource dateNanosComparatorSource(Object missingValue, MultiValueMode sortMode, Nested nested) {
|
||||
if (numericType == NumericType.DATE) {
|
||||
// converts date_nanos values to millisecond resolution
|
||||
return new LongValuesComparatorSource(this, missingValue,
|
||||
sortMode, nested, dvs -> convertNumeric(dvs, DateUtils::toNanoSeconds));
|
||||
}
|
||||
return new LongValuesComparatorSource(this, missingValue, sortMode, nested);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -250,7 +172,7 @@ public class SortedNumericIndexFieldData implements IndexNumericFieldData {
|
|||
|
||||
@Override
|
||||
public SortedNumericDocValues getLongValues() {
|
||||
return convertNanosToMillis(getLongValuesAsNanos());
|
||||
return convertNumeric(getLongValuesAsNanos(), DateUtils::toMilliSeconds);
|
||||
}
|
||||
|
||||
public SortedNumericDocValues getLongValuesAsNanos() {
|
||||
|
@ -520,47 +442,4 @@ public class SortedNumericIndexFieldData implements IndexNumericFieldData {
|
|||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the values in <code>dvs</code> from nanosecond to millisecond resolution.
|
||||
*/
|
||||
static SortedNumericDocValues convertNanosToMillis(SortedNumericDocValues dvs) {
|
||||
return convertNumeric(dvs, DateUtils::toMilliSeconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the values in <code>dvs</code> from millisecond to nanosecond resolution.
|
||||
*/
|
||||
static SortedNumericDocValues convertMillisToNanos(SortedNumericDocValues values) {
|
||||
return convertNumeric(values, DateUtils::toNanoSeconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the values in <code>dvs</code> using the provided <code>converter</code>.
|
||||
*/
|
||||
private static SortedNumericDocValues convertNumeric(SortedNumericDocValues values, LongUnaryOperator converter) {
|
||||
return new AbstractSortedNumericDocValues() {
|
||||
|
||||
@Override
|
||||
public boolean advanceExact(int target) throws IOException {
|
||||
return values.advanceExact(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long nextValue() throws IOException {
|
||||
return converter.applyAsLong(values.nextValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int docValueCount() {
|
||||
return values.docValueCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextDoc() throws IOException {
|
||||
return values.nextDoc();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -44,7 +44,6 @@ import org.elasticsearch.index.fielddata.IndexFieldData;
|
|||
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
||||
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
||||
import org.elasticsearch.index.fielddata.IndexNumericFieldData.NumericType;
|
||||
import org.elasticsearch.index.fielddata.plain.SortedNumericIndexFieldData;
|
||||
import org.elasticsearch.index.mapper.DateFieldMapper.DateFieldType;
|
||||
import org.elasticsearch.index.mapper.KeywordFieldMapper;
|
||||
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||
|
@ -53,9 +52,9 @@ import org.elasticsearch.index.query.QueryBuilder;
|
|||
import org.elasticsearch.index.query.QueryRewriteContext;
|
||||
import org.elasticsearch.index.query.QueryShardContext;
|
||||
import org.elasticsearch.index.query.QueryShardException;
|
||||
import org.elasticsearch.search.SearchSortValuesAndFormats;
|
||||
import org.elasticsearch.search.DocValueFormat;
|
||||
import org.elasticsearch.search.MultiValueMode;
|
||||
import org.elasticsearch.search.SearchSortValuesAndFormats;
|
||||
import org.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -411,7 +410,7 @@ public class FieldSortBuilder extends SortBuilder<FieldSortBuilder> {
|
|||
throw new QueryShardException(context,
|
||||
"[numeric_type] option cannot be set on a non-numeric field, got " + fieldType.typeName());
|
||||
}
|
||||
SortedNumericIndexFieldData numericFieldData = (SortedNumericIndexFieldData) fieldData;
|
||||
IndexNumericFieldData numericFieldData = (IndexNumericFieldData) fieldData;
|
||||
NumericType resolvedType = resolveNumericType(numericType);
|
||||
field = numericFieldData.sortField(resolvedType, missing, localSortMode(), nested, reverse);
|
||||
} else {
|
||||
|
@ -487,7 +486,11 @@ public class FieldSortBuilder extends SortBuilder<FieldSortBuilder> {
|
|||
throw new QueryShardException(context, "we only support AVG, MEDIAN and SUM on number based fields");
|
||||
}
|
||||
if (numericType != null) {
|
||||
SortedNumericIndexFieldData numericFieldData = (SortedNumericIndexFieldData) fieldData;
|
||||
if (fieldData instanceof IndexNumericFieldData == false) {
|
||||
throw new QueryShardException(context,
|
||||
"[numeric_type] option cannot be set on a non-numeric field, got " + fieldType.typeName());
|
||||
}
|
||||
IndexNumericFieldData numericFieldData = (IndexNumericFieldData) fieldData;
|
||||
NumericType resolvedType = resolveNumericType(numericType);
|
||||
return numericFieldData.newBucketedSort(resolvedType, context.bigArrays(), missing, localSortMode(), nested, order,
|
||||
fieldType.docValueFormat(null, null), bucketSize, extra);
|
||||
|
|
|
@ -54,11 +54,11 @@ import org.elasticsearch.common.lucene.search.function.ScoreFunction;
|
|||
import org.elasticsearch.common.lucene.search.function.WeightFactorFunction;
|
||||
import org.elasticsearch.common.util.BigArrays;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.fielddata.LeafFieldData;
|
||||
import org.elasticsearch.index.fielddata.LeafNumericFieldData;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
|
||||
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
||||
import org.elasticsearch.index.fielddata.LeafFieldData;
|
||||
import org.elasticsearch.index.fielddata.LeafNumericFieldData;
|
||||
import org.elasticsearch.index.fielddata.ScriptDocValues;
|
||||
import org.elasticsearch.index.fielddata.SortedBinaryDocValues;
|
||||
import org.elasticsearch.index.fielddata.SortedNumericDoubleValues;
|
||||
|
@ -169,7 +169,7 @@ public class FunctionScoreTests extends ESTestCase {
|
|||
/**
|
||||
* Stub for IndexNumericFieldData needed by some score functions. Returns 1 as value always.
|
||||
*/
|
||||
private static class IndexNumericFieldDataStub implements IndexNumericFieldData {
|
||||
private static class IndexNumericFieldDataStub extends IndexNumericFieldData {
|
||||
|
||||
@Override
|
||||
public NumericType getNumericType() {
|
||||
|
@ -241,15 +241,8 @@ public class FunctionScoreTests extends ESTestCase {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SortField sortField(@Nullable Object missingValue, MultiValueMode sortMode,
|
||||
XFieldComparatorSource.Nested nested, boolean reverse) {
|
||||
throw new UnsupportedOperationException(UNSUPPORTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BucketedSort newBucketedSort(BigArrays bigArrays, Object missingValue, MultiValueMode sortMode, Nested nested,
|
||||
SortOrder sortOrder, DocValueFormat format, int bucketSize, BucketedSort.ExtraData extra) {
|
||||
throw new UnsupportedOperationException(UNSUPPORTED);
|
||||
protected boolean sortRequiresCustomComparator() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue