Skip to content

Commit 4bf2de7

Browse files
authored
[Discover] Change default sort handling (#85561)
1 parent 122f1e1 commit 4bf2de7

File tree

8 files changed

+140
-14
lines changed

8 files changed

+140
-14
lines changed

src/plugins/discover/public/application/angular/discover.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,13 @@ import {
6565
MODIFY_COLUMNS_ON_SWITCH,
6666
SAMPLE_SIZE_SETTING,
6767
SEARCH_ON_PAGE_LOAD_SETTING,
68+
SORT_DEFAULT_ORDER_SETTING,
6869
} from '../../../common';
6970
import { loadIndexPattern, resolveIndexPattern } from '../helpers/resolve_index_pattern';
7071
import { getTopNavLinks } from '../components/top_nav/get_top_nav_links';
7172
import { updateSearchSource } from '../helpers/update_search_source';
7273
import { calcFieldCounts } from '../helpers/calc_field_counts';
74+
import { getDefaultSort } from './doc_table/lib/get_default_sort';
7375

7476
const services = getServices();
7577

@@ -410,9 +412,13 @@ function discoverController($element, $route, $scope, $timeout, Promise, uiCapab
410412

411413
function getStateDefaults() {
412414
const query = $scope.searchSource.getField('query') || data.query.queryString.getDefaultQuery();
415+
const sort = getSortArray(savedSearch.sort, $scope.indexPattern);
416+
413417
return {
414418
query,
415-
sort: getSortArray(savedSearch.sort, $scope.indexPattern),
419+
sort: !sort.length
420+
? getDefaultSort($scope.indexPattern, config.get(SORT_DEFAULT_ORDER_SETTING, 'desc'))
421+
: sort,
416422
columns:
417423
savedSearch.columns.length > 0
418424
? savedSearch.columns
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
import { getDefaultSort } from './get_default_sort';
20+
// @ts-ignore
21+
import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern';
22+
import { IndexPattern } from '../../../../kibana_services';
23+
24+
describe('getDefaultSort function', function () {
25+
let indexPattern: IndexPattern;
26+
beforeEach(() => {
27+
indexPattern = FixturesStubbedLogstashIndexPatternProvider() as IndexPattern;
28+
});
29+
test('should be a function', function () {
30+
expect(typeof getDefaultSort === 'function').toBeTruthy();
31+
});
32+
33+
test('should return default sort for an index pattern with timeFieldName', function () {
34+
expect(getDefaultSort(indexPattern, 'desc')).toEqual([['time', 'desc']]);
35+
expect(getDefaultSort(indexPattern, 'asc')).toEqual([['time', 'asc']]);
36+
});
37+
38+
test('should return default sort for an index pattern without timeFieldName', function () {
39+
delete indexPattern.timeFieldName;
40+
expect(getDefaultSort(indexPattern, 'desc')).toEqual([]);
41+
expect(getDefaultSort(indexPattern, 'asc')).toEqual([]);
42+
});
43+
});

src/plugins/discover/public/application/angular/doc_table/lib/get_default_sort.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
* under the License.
1818
*/
1919
import { IndexPattern } from '../../../../kibana_services';
20-
// @ts-ignore
2120
import { isSortable } from './get_sort';
2221
import { SortOrder } from '../components/table_header/helpers';
2322

@@ -26,12 +25,12 @@ import { SortOrder } from '../components/table_header/helpers';
2625
* the default sort is returned depending of the index pattern
2726
*/
2827
export function getDefaultSort(
29-
indexPattern: IndexPattern,
28+
indexPattern: IndexPattern | undefined,
3029
defaultSortOrder: string = 'desc'
3130
): SortOrder[] {
32-
if (indexPattern.timeFieldName && isSortable(indexPattern.timeFieldName, indexPattern)) {
31+
if (indexPattern?.timeFieldName && isSortable(indexPattern.timeFieldName, indexPattern)) {
3332
return [[indexPattern.timeFieldName, defaultSortOrder]];
3433
} else {
35-
return [['_score', defaultSortOrder]];
34+
return [];
3635
}
3736
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
import { getSortForSearchSource } from './get_sort_for_search_source';
20+
// @ts-ignore
21+
import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern';
22+
import { IndexPattern } from '../../../../kibana_services';
23+
import { SortOrder } from '../components/table_header/helpers';
24+
25+
describe('getSortForSearchSource function', function () {
26+
let indexPattern: IndexPattern;
27+
beforeEach(() => {
28+
indexPattern = FixturesStubbedLogstashIndexPatternProvider() as IndexPattern;
29+
});
30+
test('should be a function', function () {
31+
expect(typeof getSortForSearchSource === 'function').toBeTruthy();
32+
});
33+
34+
test('should return an object to use for searchSource when columns are given', function () {
35+
const cols = [['bytes', 'desc']] as SortOrder[];
36+
expect(getSortForSearchSource(cols, indexPattern)).toEqual([{ bytes: 'desc' }]);
37+
expect(getSortForSearchSource(cols, indexPattern, 'asc')).toEqual([{ bytes: 'desc' }]);
38+
delete indexPattern.timeFieldName;
39+
expect(getSortForSearchSource(cols, indexPattern)).toEqual([{ bytes: 'desc' }]);
40+
expect(getSortForSearchSource(cols, indexPattern, 'asc')).toEqual([{ bytes: 'desc' }]);
41+
});
42+
43+
test('should return an object to use for searchSource when no columns are given', function () {
44+
const cols = [] as SortOrder[];
45+
expect(getSortForSearchSource(cols, indexPattern)).toEqual([{ _doc: 'desc' }]);
46+
expect(getSortForSearchSource(cols, indexPattern, 'asc')).toEqual([{ _doc: 'asc' }]);
47+
delete indexPattern.timeFieldName;
48+
expect(getSortForSearchSource(cols, indexPattern)).toEqual([{ _score: 'desc' }]);
49+
expect(getSortForSearchSource(cols, indexPattern, 'asc')).toEqual([{ _score: 'asc' }]);
50+
});
51+
});

src/plugins/discover/public/application/angular/doc_table/lib/get_sort_for_search_source.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import { EsQuerySortValue, IndexPattern } from '../../../../kibana_services';
2020
import { SortOrder } from '../components/table_header/helpers';
2121
import { getSort } from './get_sort';
22-
import { getDefaultSort } from './get_default_sort';
2322

2423
/**
2524
* Prepares sort for search source, that's sending the request to ES
@@ -33,10 +32,13 @@ export function getSortForSearchSource(
3332
indexPattern?: IndexPattern,
3433
defaultDirection: string = 'desc'
3534
): EsQuerySortValue[] {
36-
if (!sort || !indexPattern) {
37-
return [];
38-
} else if (Array.isArray(sort) && sort.length === 0) {
39-
sort = getDefaultSort(indexPattern, defaultDirection);
35+
if (!sort || !indexPattern || (Array.isArray(sort) && sort.length === 0)) {
36+
if (indexPattern?.timeFieldName) {
37+
// sorting by index order
38+
return [{ _doc: defaultDirection } as EsQuerySortValue];
39+
} else {
40+
return [{ _score: defaultDirection } as EsQuerySortValue];
41+
}
4042
}
4143
const { timeFieldName } = indexPattern;
4244
return getSort(sort, indexPattern).map((sortPair: Record<string, string>) => {

src/plugins/discover/public/application/embeddable/search_embeddable.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import {
4848
import { SEARCH_EMBEDDABLE_TYPE } from './constants';
4949
import { SavedSearch } from '../..';
5050
import { SAMPLE_SIZE_SETTING, SORT_DEFAULT_ORDER_SETTING } from '../../../common';
51+
import { getDefaultSort } from '../angular/doc_table/lib/get_default_sort';
5152

5253
interface SearchScope extends ng.IScope {
5354
columns?: string[];
@@ -200,6 +201,13 @@ export class SearchEmbeddable
200201
const { searchSource } = this.savedSearch;
201202
const indexPattern = (searchScope.indexPattern = searchSource.getField('index'))!;
202203

204+
if (!this.savedSearch.sort || !this.savedSearch.sort.length) {
205+
this.savedSearch.sort = getDefaultSort(
206+
indexPattern,
207+
getServices().uiSettings.get(SORT_DEFAULT_ORDER_SETTING, 'desc')
208+
);
209+
}
210+
203211
const timeRangeSearchSource = searchSource.create();
204212
timeRangeSearchSource.setField('filter', () => {
205213
if (!this.searchScope || !this.input.timeRange) return;
@@ -341,7 +349,14 @@ export class SearchEmbeddable
341349
// If there is column or sort data on the panel, that means the original columns or sort settings have
342350
// been overridden in a dashboard.
343351
searchScope.columns = this.input.columns || this.savedSearch.columns;
344-
searchScope.sort = this.input.sort || this.savedSearch.sort;
352+
const savedSearchSort =
353+
this.savedSearch.sort && this.savedSearch.sort.length
354+
? this.savedSearch.sort
355+
: getDefaultSort(
356+
this.searchScope?.indexPattern,
357+
getServices().uiSettings.get(SORT_DEFAULT_ORDER_SETTING, 'desc')
358+
);
359+
searchScope.sort = this.input.sort || savedSearchSort;
345360
searchScope.sharedItemTitle = this.panelTitle;
346361

347362
if (forceFetch || isFetchRequired) {

src/plugins/discover/public/application/helpers/get_sharing_data.test.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { getSharingData } from './get_sharing_data';
2121
import { IUiSettingsClient } from 'kibana/public';
2222
import { createSearchSourceMock } from '../../../../data/common/search/search_source/mocks';
2323
import { indexPatternMock } from '../../__mocks__/index_pattern';
24+
import { SORT_DEFAULT_ORDER_SETTING } from '../../../common';
2425

2526
describe('getSharingData', () => {
2627
test('returns valid data for sharing', async () => {
@@ -29,7 +30,10 @@ describe('getSharingData', () => {
2930
searchSourceMock,
3031
{ columns: [] },
3132
({
32-
get: () => {
33+
get: (key: string) => {
34+
if (key === SORT_DEFAULT_ORDER_SETTING) {
35+
return 'desc';
36+
}
3337
return false;
3438
},
3539
} as unknown) as IUiSettingsClient,
@@ -57,7 +61,13 @@ describe('getSharingData', () => {
5761
},
5862
},
5963
"script_fields": Object {},
60-
"sort": Array [],
64+
"sort": Array [
65+
Object {
66+
"_score": Object {
67+
"order": "desc",
68+
},
69+
},
70+
],
6171
"stored_fields": undefined,
6272
},
6373
"index": "the-index-pattern-title",

test/functional/apps/discover/_shared_links.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
9090
":(from:'2015-09-19T06:31:44.000Z',to:'2015-09" +
9191
"-23T18:31:44.000Z'))&_a=(columns:!(_source),filters:!(),index:'logstash-" +
9292
"*',interval:auto,query:(language:kuery,query:'')" +
93-
',sort:!())';
93+
",sort:!(!('@timestamp',desc)))";
9494
const actualUrl = await PageObjects.share.getSharedUrl();
9595
// strip the timestamp out of each URL
9696
expect(actualUrl.replace(/_t=\d{13}/, '_t=TIMESTAMP')).to.be(

0 commit comments

Comments
 (0)