Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ public Sort buildIndexSort(
if (fieldData == null) {
throw new IllegalArgumentException("docvalues not found for index sort field:[" + sortSpec.field + "]");
}
sortFields[i] = fieldData.sortField(this.indexCreatedVersion, sortSpec.missingValue, mode, null, reverse);
sortFields[i] = fieldData.indexSort(this.indexCreatedVersion, sortSpec.missingValue, mode, reverse);
validateIndexSortField(sortFields[i]);
}
return new Sort(sortFields);
Expand Down Expand Up @@ -430,6 +430,8 @@ public static SortField.Type getSortFieldType(SortField sortField) {
return SortField.Type.STRING;
} else if (sortField instanceof SortedNumericSortField) {
return ((SortedNumericSortField) sortField).getNumericType();
} else if (sortField.getComparatorSource() instanceof IndexFieldData.XFieldComparatorSource fcs) {
return fcs.sortType();
} else {
return sortField.getType();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,20 @@ public interface IndexFieldData<FD extends LeafFieldData> {
* Returns the {@link SortField} to use for sorting depending on the version of the index.
*/
default SortField sortField(
boolean indexSort,
IndexVersion indexCreatedVersion,
@Nullable Object missingValue,
MultiValueMode sortMode,
Nested nested,
boolean reverse
) {
return sortField(missingValue, sortMode, nested, reverse);
return indexSort
? indexSort(indexCreatedVersion, missingValue, sortMode, reverse)
: sortField(missingValue, sortMode, nested, reverse);
}

default SortField indexSort(IndexVersion indexCreatedVersion, @Nullable Object missingValue, MultiValueMode sortMode, boolean reverse) {
return sortField(missingValue, sortMode, null, reverse);
}

/**
Expand Down Expand Up @@ -231,6 +238,10 @@ public Object missingObject(Object missingValue, boolean reversed) {

public abstract SortField.Type reducedType();

public SortField.Type sortType() {
return reducedType();
}

/**
* Return a missing value that is understandable by {@link SortField#setMissingValue(Object)}.
* Most implementations return null because they already replace the value at the fielddata level.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ public final ValuesSourceType getValuesSourceType() {
* match the field's <code>numericType</code>.
*/
public final SortField sortField(
boolean indexSort,
NumericType targetNumericType,
Object missingValue,
MultiValueMode sortMode,
Expand All @@ -104,7 +105,7 @@ public final SortField sortField(
boolean requiresCustomComparator = nested != null
|| (sortMode != MultiValueMode.MAX && sortMode != MultiValueMode.MIN)
|| targetNumericType != getNumericType();
if (sortRequiresCustomComparator() || requiresCustomComparator) {
if (indexSort == false || sortRequiresCustomComparator()) {
SortField sortField = new SortField(getFieldName(), source, reverse);
sortField.setOptimizeSortWithPoints(requiresCustomComparator == false && canUseOptimizedSort(indexType()));
return sortField;
Expand Down Expand Up @@ -138,18 +139,24 @@ private static boolean canUseOptimizedSort(IndexType indexType) {

@Override
public final SortField sortField(Object missingValue, MultiValueMode sortMode, Nested nested, boolean reverse) {
return sortField(getNumericType(), missingValue, sortMode, nested, reverse);
return sortField(false, getNumericType(), missingValue, sortMode, nested, reverse);
}

@Override
public SortField indexSort(IndexVersion indexCreatedVersion, Object missingValue, MultiValueMode sortMode, boolean reverse) {
return sortField(true, indexCreatedVersion, missingValue, sortMode, null, reverse);
}

@Override
public SortField sortField(
boolean indexSort,
IndexVersion indexCreatedVersion,
Object missingValue,
MultiValueMode sortMode,
Nested nested,
boolean reverse
) {
SortField sortField = sortField(missingValue, sortMode, nested, reverse);
SortField sortField = sortField(indexSort, getNumericType(), missingValue, sortMode, nested, reverse);
if (getNumericType() == NumericType.DATE_NANOSECONDS
&& indexCreatedVersion.before(IndexVersions.V_7_14_0)
&& missingValue.equals("_last")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,7 @@ public FieldComparator<?> newComparator(String fieldname, int numHits, Pruning e
assert indexFieldData == null || fieldname.equals(indexFieldData.getFieldName());

final double dMissingValue = (Double) missingObject(missingValue, reversed);
// NOTE: it's important to pass null as a missing value in the constructor so that
// the comparator doesn't check docsWithField since we replace missing values in select()
return new DoubleComparator(numHits, fieldname, null, reversed, enableSkipping) {
return new DoubleComparator(numHits, fieldname, dMissingValue, reversed, enableSkipping) {
@Override
public LeafFieldComparator getLeafComparator(LeafReaderContext context) throws IOException {
return new DoubleLeafComparator(context) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public FieldComparator<?> newComparator(String fieldname, int numHits, Pruning e
final float fMissingValue = (Float) missingObject(missingValue, reversed);
// NOTE: it's important to pass null as a missing value in the constructor so that
// the comparator doesn't check docsWithField since we replace missing values in select()
return new FloatComparator(numHits, fieldname, null, reversed, enableSkipping) {
return new FloatComparator(numHits, fieldname, fMissingValue, reversed, enableSkipping) {
@Override
public LeafFieldComparator getLeafComparator(LeafReaderContext context) throws IOException {
return new FloatLeafComparator(context) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.apache.lucene.search.FieldComparator;
import org.apache.lucene.search.LeafFieldComparator;
import org.apache.lucene.search.Pruning;
import org.apache.lucene.search.SortField;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.index.fielddata.DenseDoubleValues;
import org.elasticsearch.index.fielddata.IndexNumericFieldData;
Expand All @@ -33,14 +34,17 @@ public HalfFloatValuesComparatorSource(
super(indexFieldData, missingValue, sortMode, nested);
}

@Override
public SortField.Type sortType() {
return SortField.Type.CUSTOM;
}

@Override
public FieldComparator<?> newComparator(String fieldname, int numHits, Pruning enableSkipping, boolean reversed) {
assert indexFieldData == null || fieldname.equals(indexFieldData.getFieldName());

final float fMissingValue = (Float) missingObject(missingValue, reversed);
// NOTE: it's important to pass null as a missing value in the constructor so that
// the comparator doesn't check docsWithField since we replace missing values in select()
return new HalfFloatComparator(numHits, fieldname, null, reversed, enableSkipping) {
return new HalfFloatComparator(numHits, fieldname, fMissingValue, reversed, enableSkipping) {
@Override
public LeafFieldComparator getLeafComparator(LeafReaderContext context) throws IOException {
return new HalfFloatLeafComparator(context) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,7 @@ public FieldComparator<?> newComparator(String fieldname, int numHits, Pruning e
assert indexFieldData == null || fieldname.equals(indexFieldData.getFieldName());

final int iMissingValue = (Integer) missingObject(missingValue, reversed);
// NOTE: it's important to pass null as a missing value in the constructor so that
// the comparator doesn't check docsWithField since we replace missing values in select()
return new IntComparator(numHits, fieldname, null, reversed, enableSkipping) {
return new IntComparator(numHits, fieldname, iMissingValue, reversed, enableSkipping) {
@Override
public LeafFieldComparator getLeafComparator(LeafReaderContext context) throws IOException {
return new IntLeafComparator(context) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,7 @@ public FieldComparator<?> newComparator(String fieldname, int numHits, Pruning e
assert indexFieldData == null || fieldname.equals(indexFieldData.getFieldName());

final long lMissingValue = (Long) missingObject(missingValue, reversed);
// NOTE: it's important to pass null as a missing value in the constructor so that
// the comparator doesn't check docsWithField since we replace missing values in select()
return new XLongComparator(numHits, fieldname, null, reversed, enableSkipping) {
return new XLongComparator(numHits, fieldname, lMissingValue, reversed, enableSkipping) {
@Override
public LeafFieldComparator getLeafComparator(LeafReaderContext context) throws IOException {
final int maxDoc = context.reader().maxDoc();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,8 @@ public int docIDRunEnd() throws IOException {
return super.docIDRunEnd();
}
}

public DocIdSetIterator getDelegate() {
return in;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -355,10 +355,10 @@ public SortFieldAndFormat build(SearchExecutionContext context) throws IOExcepti
}
IndexNumericFieldData numericFieldData = (IndexNumericFieldData) fieldData;
NumericType resolvedType = resolveNumericType(numericType);
field = numericFieldData.sortField(resolvedType, missing, localSortMode(), nested, reverse);
field = numericFieldData.sortField(false, resolvedType, missing, localSortMode(), nested, reverse);
isNanosecond = resolvedType == NumericType.DATE_NANOSECONDS;
} else {
field = fieldData.sortField(context.indexVersionCreated(), missing, localSortMode(), nested, reverse);
field = fieldData.sortField(false, context.indexVersionCreated(), missing, localSortMode(), nested, reverse);
if (fieldData instanceof IndexNumericFieldData) {
isNanosecond = ((IndexNumericFieldData) fieldData).getNumericType() == NumericType.DATE_NANOSECONDS;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.store.Directory;
Expand All @@ -34,6 +35,7 @@
import org.elasticsearch.index.codec.tsdb.es819.ES819TSDBDocValuesFormat;
import org.elasticsearch.index.mapper.DateFieldMapper.DateFieldType;
import org.elasticsearch.index.mapper.blockloader.docvalues.LongsBlockLoader;
import org.elasticsearch.lucene.comparators.XUpdateableDocIdSetIterator;
import org.elasticsearch.script.DateFieldScript;
import org.elasticsearch.script.ScriptService;
import org.elasticsearch.search.DocValueFormat;
Expand All @@ -48,6 +50,7 @@
import java.time.ZonedDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.IntStream;
import java.util.stream.Stream;

Expand Down Expand Up @@ -915,6 +918,12 @@ public void testSingletonLongBulkBlockReadingManyValues() throws Exception {
}
}

private static final Consumer<DocIdSetIterator> checkClass = disi -> {
assertThat(disi, instanceOf(XUpdateableDocIdSetIterator.class));
XUpdateableDocIdSetIterator iterator = (XUpdateableDocIdSetIterator) disi;
assertThat(iterator.getDelegate().getClass().getName(), containsString("SecondarySortIterator"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice 👍

};

@Override
protected List<SortShortcutSupport> getSortShortcutSupport() {
return List.of(
Expand All @@ -925,7 +934,7 @@ protected List<SortShortcutSupport> getSortShortcutSupport() {
b -> b.field("type", "date").field("ignore_malformed", false),
b -> b.startObject("host.name").field("type", "keyword").endObject(),
b -> b.field("@timestamp", "2025-10-30T00:00:00").field("host.name", "foo"),
true
checkClass
),
new SortShortcutSupport(b -> b.field("type", "date"), b -> b.field("field", "2025-10-30T00:00:00"), true),
new SortShortcutSupport(b -> b.field("type", "date_nanos"), b -> b.field("field", "2025-10-30T00:00:00"), true),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,7 @@ public void doTestIndexSortRangeQueries(NumberType type, Supplier<Number> valueS
NumberFieldType fieldType = new NumberFieldType("field", type);
IndexNumericFieldData fielddata = (IndexNumericFieldData) fieldType.fielddataBuilder(FieldDataContext.noRuntimeFields("test"))
.build(null, null);
SortField sortField = fielddata.sortField(null, MultiValueMode.MIN, null, randomBoolean());
SortField sortField = fielddata.indexSort(IndexVersion.current(), null, MultiValueMode.MIN, randomBoolean());

IndexWriterConfig writerConfig = new IndexWriterConfig();
writerConfig.setIndexSort(new Sort(sortField));
Expand Down
Loading