19
19
import org .elasticsearch .index .fielddata .IndexFieldData .XFieldComparatorSource .Nested ;
20
20
import org .elasticsearch .index .fielddata .fieldcomparator .DoubleValuesComparatorSource ;
21
21
import org .elasticsearch .index .fielddata .fieldcomparator .FloatValuesComparatorSource ;
22
+ import org .elasticsearch .index .fielddata .fieldcomparator .HalfFloatValuesComparatorSource ;
22
23
import org .elasticsearch .index .fielddata .fieldcomparator .LongValuesComparatorSource ;
23
24
import org .elasticsearch .search .DocValueFormat ;
24
25
import org .elasticsearch .search .MultiValueMode ;
@@ -46,7 +47,7 @@ public enum NumericType {
46
47
LONG (false , SortField .Type .LONG , CoreValuesSourceType .NUMERIC ),
47
48
DATE (false , SortField .Type .LONG , CoreValuesSourceType .DATE ),
48
49
DATE_NANOSECONDS (false , SortField .Type .LONG , CoreValuesSourceType .DATE ),
49
- HALF_FLOAT (true , SortField .Type .LONG , CoreValuesSourceType .NUMERIC ),
50
+ HALF_FLOAT (true , SortField .Type .FLOAT , CoreValuesSourceType .NUMERIC ),
50
51
FLOAT (true , SortField .Type .FLOAT , CoreValuesSourceType .NUMERIC ),
51
52
DOUBLE (true , SortField .Type .DOUBLE , CoreValuesSourceType .NUMERIC );
52
53
@@ -95,11 +96,13 @@ public final SortField sortField(
95
96
* 3. We Aren't using max or min to resolve the duplicates.
96
97
* 4. We have to cast the results to another type.
97
98
*/
98
- if (sortRequiresCustomComparator ()
99
- || nested != null
99
+ boolean requiresCustomComparator = nested != null
100
100
|| (sortMode != MultiValueMode .MAX && sortMode != MultiValueMode .MIN )
101
- || targetNumericType != getNumericType ()) {
102
- return new SortField (getFieldName (), source , reverse );
101
+ || targetNumericType != getNumericType ();
102
+ if (sortRequiresCustomComparator () || requiresCustomComparator ) {
103
+ SortField sortField = new SortField (getFieldName (), source , reverse );
104
+ sortField .setOptimizeSortWithPoints (requiresCustomComparator == false && isIndexed ());
105
+ return sortField ;
103
106
}
104
107
105
108
SortedNumericSelector .Type selectorType = sortMode == MultiValueMode .MAX
@@ -108,20 +111,18 @@ public final SortField sortField(
108
111
SortField sortField = new SortedNumericSortField (getFieldName (), getNumericType ().sortFieldType , reverse , selectorType );
109
112
sortField .setMissingValue (source .missingObject (missingValue , reverse ));
110
113
111
- // TODO: Now that numeric sort uses indexed points to skip over non-competitive documents,
112
- // Lucene 9 requires that the same data/type is stored in points and doc values.
113
- // We break this assumption in ES by using the wider numeric sort type for every field,
114
- // (e.g. shorts use longs and floats use doubles). So for now we forbid the usage of
115
- // points in numeric sort on field types that use a different sort type.
116
- // We could expose these optimizations for all numeric types but that would require
117
- // to rewrite the logic to handle types when merging results coming from different
118
- // indices.
114
+ // TODO: enable sort optimization for BYTE, SHORT and INT types
115
+ // They can use custom comparator logic, similarly to HalfFloatValuesComparatorSource.
116
+ // The problem comes from the fact that we use SortField.Type.LONG for all these types.
117
+ // Investigate how to resolve this.
119
118
switch (getNumericType ()) {
120
119
case DATE_NANOSECONDS :
121
120
case DATE :
122
121
case LONG :
123
122
case DOUBLE :
124
- // longs, doubles and dates use the same type for doc-values and points.
123
+ case FLOAT :
124
+ // longs, doubles and dates use the same type for doc-values and points
125
+ // floats uses longs for doc-values, but Lucene's FloatComparator::getValueForDoc converts long value to float
125
126
sortField .setOptimizeSortWithPoints (isIndexed ());
126
127
break ;
127
128
@@ -199,7 +200,8 @@ private XFieldComparatorSource comparatorSource(
199
200
Nested nested
200
201
) {
201
202
return switch (targetNumericType ) {
202
- case HALF_FLOAT , FLOAT -> new FloatValuesComparatorSource (this , missingValue , sortMode , nested );
203
+ case FLOAT -> new FloatValuesComparatorSource (this , missingValue , sortMode , nested );
204
+ case HALF_FLOAT -> new HalfFloatValuesComparatorSource (this , missingValue , sortMode , nested );
203
205
case DOUBLE -> new DoubleValuesComparatorSource (this , missingValue , sortMode , nested );
204
206
case DATE -> dateComparatorSource (missingValue , sortMode , nested );
205
207
case DATE_NANOSECONDS -> dateNanosComparatorSource (missingValue , sortMode , nested );
0 commit comments