Skip to content

Use the correct type to widen the sort fields when merging top field docsΒ #16860

Closed
@bugmakerrrrrr

Description

@bugmakerrrrrr

Describe the bug

To enable numeric sort optimization support for all numeric types, we use double to widen the sort fields in #6424. However, when the sort value exceeds the MAX_SAFE_INTEGER (2^53 – 1), it may result in incorrect sorting.

Related component

Search

To Reproduce

public class FieldSortIT extends ParameterizedDynamicSettingsOpenSearchIntegTestCase {
    public void testSortMixedNumericField() throws Exception {
            internalCluster().ensureAtLeastNumDataNodes(3);
            index("long", Long.MAX_VALUE);
            index("integer", Integer.MAX_VALUE);
            SearchResponse searchResponse = client().prepareSearch("long", "integer")
                .setQuery(matchAllQuery())
                .setSize(10)
                .addSort(SortBuilders.fieldSort("field").order(SortOrder.ASC).sortMode(SortMode.MAX))
                .get();
            assertNoFailures(searchResponse);
            long[] sortValues = new long[10];
            for (int i = 0; i < 10; i++) {
                sortValues[i] = ((Number) searchResponse.getHits().getAt(i).getSortValues()[0]).longValue();
            }
            for (int i = 1; i < 10; i++) {
                assertThat(Arrays.toString(sortValues), sortValues[i - 1], lessThan(sortValues[i]));
            }
        }
    
        private void index(String type, long end) throws Exception {
            assertAcked(
                prepareCreate(type).setMapping(
                    XContentFactory.jsonBuilder()
                        .startObject()
                        .startObject("properties")
                        .startObject("field")
                        .field("type", type)
                        .endObject()
                        .endObject()
                        .endObject()
                ).setSettings(Settings.builder().put("index.number_of_shards", 3).put("index.number_of_replicas", 0))
            );
            ensureGreen(type);
            for (int i = 0; i < 5; i++) {
                client().prepareIndex(type).setId(Integer.toString(i)).setSource("{\"field\" : " + (end - i) + " }", XContentType.JSON).get();
            }
            client().admin().indices().prepareRefresh(type).get();
        }
}

Expected behavior

When the sort values are all integer values, we can use the Long type to widen the sort fields.

To be discussed: 1. When sort values contain both integer values and float values, should we throw an exception or use double to widen sort fields? 2. Should we check the compatibility between sort types when merging top docs?

Additional Details

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    SearchSearch query, autocomplete ...etcbugSomething isn't workingv2.19.0Issues and PRs related to version 2.19.0v3.0.0Issues and PRs related to version 3.0.0

    Type

    No type

    Projects

    Status

    βœ… Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions