diff --git a/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.md b/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.md index 7ab02187859edd1..9e09bc3ace5577b 100644 --- a/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.md +++ b/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.md @@ -25,7 +25,7 @@ export interface SavedObjectsFindOptions extends SavedObjectsBaseOptions | [rawSearchFields](./kibana-plugin-core-public.savedobjectsfindoptions.rawsearchfields.md) | string[] | The fields to perform the parsed query against. Unlike the searchFields argument, these are expected to be raw and will not be modified. If used in conjunction with searchFields, both are concatenated together. | | [search](./kibana-plugin-core-public.savedobjectsfindoptions.search.md) | string | Search documents using the Elasticsearch Simple Query String syntax. See Elasticsearch Simple Query String query argument for more information | | [searchFields](./kibana-plugin-core-public.savedobjectsfindoptions.searchfields.md) | string[] | The fields to perform the parsed query against. See Elasticsearch Simple Query String fields argument for more information | -| [sortField](./kibana-plugin-core-public.savedobjectsfindoptions.sortfield.md) | string | string[] | | -| [sortOrder](./kibana-plugin-core-public.savedobjectsfindoptions.sortorder.md) | string | string[] | | +| [sortField](./kibana-plugin-core-public.savedobjectsfindoptions.sortfield.md) | string | | +| [sortOrder](./kibana-plugin-core-public.savedobjectsfindoptions.sortorder.md) | string | | | [type](./kibana-plugin-core-public.savedobjectsfindoptions.type.md) | string | string[] | | diff --git a/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.sortfield.md b/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.sortfield.md index 4336b01d6bd8cf0..7b5072c0e19dfaa 100644 --- a/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.sortfield.md +++ b/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.sortfield.md @@ -7,5 +7,5 @@ Signature: ```typescript -sortField?: string | string[]; +sortField?: string; ``` diff --git a/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.sortorder.md b/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.sortorder.md index 68540d6607b8f95..3834c802fa18453 100644 --- a/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.sortorder.md +++ b/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.sortorder.md @@ -7,5 +7,5 @@ Signature: ```typescript -sortOrder?: string | string[]; +sortOrder?: string; ``` diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.md index e13554a1a4e7273..4d6b91d16e70601 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.md @@ -25,7 +25,7 @@ export interface SavedObjectsFindOptions extends SavedObjectsBaseOptions | [rawSearchFields](./kibana-plugin-core-server.savedobjectsfindoptions.rawsearchfields.md) | string[] | The fields to perform the parsed query against. Unlike the searchFields argument, these are expected to be raw and will not be modified. If used in conjunction with searchFields, both are concatenated together. | | [search](./kibana-plugin-core-server.savedobjectsfindoptions.search.md) | string | Search documents using the Elasticsearch Simple Query String syntax. See Elasticsearch Simple Query String query argument for more information | | [searchFields](./kibana-plugin-core-server.savedobjectsfindoptions.searchfields.md) | string[] | The fields to perform the parsed query against. See Elasticsearch Simple Query String fields argument for more information | -| [sortField](./kibana-plugin-core-server.savedobjectsfindoptions.sortfield.md) | string | string[] | | -| [sortOrder](./kibana-plugin-core-server.savedobjectsfindoptions.sortorder.md) | string | string[] | | +| [sortField](./kibana-plugin-core-server.savedobjectsfindoptions.sortfield.md) | string | | +| [sortOrder](./kibana-plugin-core-server.savedobjectsfindoptions.sortorder.md) | string | | | [type](./kibana-plugin-core-server.savedobjectsfindoptions.type.md) | string | string[] | | diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.sortfield.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.sortfield.md index 2c8657ba7319cf3..1dffe996d5726ce 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.sortfield.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.sortfield.md @@ -7,5 +7,5 @@ Signature: ```typescript -sortField?: string | string[]; +sortField?: string; ``` diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.sortorder.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.sortorder.md index 23dabdf1797fc0c..d247b9e38e44896 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.sortorder.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.sortorder.md @@ -7,5 +7,5 @@ Signature: ```typescript -sortOrder?: string | string[]; +sortOrder?: string; ``` diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index 85324045421bf34..3eae0eb7ad5e682 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -1302,9 +1302,9 @@ export interface SavedObjectsFindOptions extends SavedObjectsBaseOptions { search?: string; searchFields?: string[]; // (undocumented) - sortField?: string | string[]; + sortField?: string; // (undocumented) - sortOrder?: string | string[]; + sortOrder?: string; // (undocumented) type: string | string[]; } diff --git a/src/core/server/saved_objects/service/lib/search_dsl/__snapshots__/sorting_params.test.ts.snap b/src/core/server/saved_objects/service/lib/search_dsl/__snapshots__/sorting_params.test.ts.snap new file mode 100644 index 000000000000000..8226b1c6695b47c --- /dev/null +++ b/src/core/server/saved_objects/service/lib/search_dsl/__snapshots__/sorting_params.test.ts.snap @@ -0,0 +1,9 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`searchDsl/getSortParams sort with direction sortField is non-root multi-field with multiple types returns correct params 1`] = `"Unable to sort multiple types by field title.raw, not a root property"`; + +exports[`searchDsl/getSortParams sort with direction sortFields is non-root simple property with multiple types returns correct params 1`] = `"Unable to sort multiple types by field title, not a root property"`; + +exports[`searchDsl/getSortParams sortField no direction sortField is not-root multi-field with multiple types returns correct params 1`] = `"Unable to sort multiple types by field title.raw, not a root property"`; + +exports[`searchDsl/getSortParams sortField no direction sortField is simple non-root property with multiple types returns correct params 1`] = `"Unable to sort multiple types by field title, not a root property"`; diff --git a/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.test.ts b/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.test.ts index f595eb59c19d486..226cf8e187f229f 100644 --- a/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.test.ts +++ b/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.test.ts @@ -46,17 +46,12 @@ describe('getSearchDsl', () => { }); }).toThrowError(/type must be specified/); }); - - it('throws when sortOrder is defined and sortField is undefined', () => { - expect(() => { - getSearchDsl(mappings, registry, { type: 'foo', sortOrder: 'desc' }); - }).toThrowError(/sortOrder requires a sortField/); - }); - - it('throws when sortOrder length is greater than sortField length', () => { + it('throws when sortOrder without sortField', () => { expect(() => { - const options = { type: 'foo', sortField: ['bar'], sortOrder: ['baz', 'qux'] }; - getSearchDsl(mappings, registry, options); + getSearchDsl(mappings, registry, { + type: 'foo', + sortOrder: 'desc', + }); }).toThrowError(/sortOrder requires a sortField/); }); }); @@ -91,30 +86,22 @@ describe('getSearchDsl', () => { }); }); - describe('passes (mappings, type, sortField, sortOrder) to getSortingParams', () => { - it('with string type and undefined sortField/sortOrder', () => { - getSortingParams.mockReturnValue({}); - - getSearchDsl(mappings, registry, { type: 'foo' }); - expect(getSortingParams).toHaveBeenCalledTimes(1); - expect(getSortingParams).toHaveBeenCalledWith(mappings, 'foo', [], []); - }); - - it('with strings', () => { - getSortingParams.mockReturnValue({}); - - getSearchDsl(mappings, registry, { type: 'foo', sortField: 'bar', sortOrder: 'baz' }); - expect(getSortingParams).toHaveBeenCalledTimes(1); - expect(getSortingParams).toHaveBeenCalledWith(mappings, 'foo', ['bar'], ['baz']); - }); - - it('with string arrays', () => { - getSortingParams.mockReturnValue({}); + it('passes (mappings, type, sortField, sortOrder) to getSortingParams', () => { + getSortingParams.mockReturnValue({}); + const opts = { + type: 'foo', + sortField: 'bar', + sortOrder: 'baz', + }; - getSearchDsl(mappings, registry, { type: ['foo'], sortField: ['bar'], sortOrder: ['baz'] }); - expect(getSortingParams).toHaveBeenCalledTimes(1); - expect(getSortingParams).toHaveBeenCalledWith(mappings, ['foo'], ['bar'], ['baz']); - }); + getSearchDsl(mappings, registry, opts); + expect(getSortingParams).toHaveBeenCalledTimes(1); + expect(getSortingParams).toHaveBeenCalledWith( + mappings, + opts.type, + opts.sortField, + opts.sortOrder + ); }); it('returns combination of getQueryParams and getSortingParams', () => { diff --git a/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.ts b/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.ts index 748ca3992d1ba76..d612e1006d2f3b1 100644 --- a/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.ts +++ b/src/core/server/saved_objects/service/lib/search_dsl/search_dsl.ts @@ -32,8 +32,8 @@ interface GetSearchDslOptions { defaultSearchOperator?: string; searchFields?: string[]; rawSearchFields?: string[]; - sortField?: string | string[]; - sortOrder?: string | string[]; + sortField?: string; + sortOrder?: string; namespace?: string; hasReference?: { type: string; @@ -64,10 +64,7 @@ export function getSearchDsl( throw Boom.notAcceptable('type must be specified'); } - const sortFields = sortField ? (Array.isArray(sortField) ? sortField : [sortField]) : []; - const sortOrders = sortOrder ? (Array.isArray(sortOrder) ? sortOrder : [sortOrder]) : []; - - if (sortOrders.length > sortFields.length) { + if (sortOrder && !sortField) { throw Boom.notAcceptable('sortOrder requires a sortField'); } @@ -84,6 +81,6 @@ export function getSearchDsl( hasReference, kueryNode, }), - ...getSortingParams(mappings, type, sortFields, sortOrders), + ...getSortingParams(mappings, type, sortField, sortOrder), }; } diff --git a/src/core/server/saved_objects/service/lib/search_dsl/sorting_params.test.ts b/src/core/server/saved_objects/service/lib/search_dsl/sorting_params.test.ts index dafa82c62955d85..c7a4b7df065472c 100644 --- a/src/core/server/saved_objects/service/lib/search_dsl/sorting_params.test.ts +++ b/src/core/server/saved_objects/service/lib/search_dsl/sorting_params.test.ts @@ -29,9 +29,6 @@ const MAPPINGS = { }, }, }, - updated_at: { - type: 'date', - }, pending: { properties: { title: { @@ -67,187 +64,174 @@ const MAPPINGS = { }; describe('searchDsl/getSortParams', () => { - describe('errors', () => { - it('throws an error when multiple types are used and a sort field is not a valid root property', () => { - expect(() => - getSortingParams(MAPPINGS, ['saved', 'pending'], ['title'], []) - ).toThrowErrorMatchingInlineSnapshot( - `"Unable to sort multiple types by field title, not a root property"` - ); - }); - - it('throws an error a single type is used and a sort field is not a valid simple property', () => { - expect(() => - getSortingParams(MAPPINGS, ['saved'], ['type'], []) - ).toThrowErrorMatchingInlineSnapshot(`"Unknown sort field type"`); - expect(() => - getSortingParams(MAPPINGS, ['saved'], ['foo'], []) - ).toThrowErrorMatchingInlineSnapshot(`"Unknown sort field foo"`); + describe('type, no sortField', () => { + it('returns no params', () => { + expect(getSortingParams(MAPPINGS, 'pending')).toEqual({}); }); }); - describe('results', () => { - it('returns an empty object when `sortFields` is empty', () => { - expect(getSortingParams(MAPPINGS, 'pending', [], [])).toEqual({}); + describe('type, order, no sortField', () => { + it('returns no params', () => { + expect(getSortingParams(MAPPINGS, 'saved', undefined, 'desc')).toEqual({}); }); + }); - describe('top-level fields', () => { - const type = 'saved'; // specific type doesn't matter for these test cases, it just needs to be valid - - it('single sort field without a sort order', () => { - const { sort } = getSortingParams(MAPPINGS, type, ['_id'], []); - expect(sort).toEqual([{ _id: { order: undefined } }]); - }); - - it('single sort field with a single sort order', () => { - const { sort } = getSortingParams(MAPPINGS, type, ['_id'], ['foo']); - expect(sort).toEqual([{ _id: { order: 'foo' } }]); - }); - - it('single sort field with multiple sort orders', () => { - const { sort } = getSortingParams(MAPPINGS, type, ['_id'], ['foo', 'bar']); - expect(sort).toEqual([{ _id: { order: 'foo' } }]); - }); - - it('multiple sort fields without a sort order', () => { - const { sort } = getSortingParams(MAPPINGS, type, ['_id', '_score'], []); - expect(sort).toEqual([{ _id: { order: undefined } }, { _score: { order: undefined } }]); - }); - - it('multiple sort fields with a single sort order', () => { - const { sort } = getSortingParams(MAPPINGS, type, ['_id', '_score'], ['foo']); - expect(sort).toEqual([{ _id: { order: 'foo' } }, { _score: { order: undefined } }]); - }); - - it('multiple sort fields with multiple sort orders', () => { - const { sort } = getSortingParams(MAPPINGS, type, ['_id', '_score'], ['foo', 'bar']); - expect(sort).toEqual([{ _id: { order: 'foo' } }, { _score: { order: 'bar' } }]); + describe('sortField no direction', () => { + describe('sortField is simple property with single type', () => { + it('returns correct params', () => { + expect(getSortingParams(MAPPINGS, 'saved', 'title')).toEqual({ + sort: [ + { + 'saved.title': { + order: undefined, + unmapped_type: 'text', + }, + }, + ], + }); }); }); - - describe('root properties', () => { - const types = ['saved', 'pending']; - - it('single sort field without a sort order', () => { - const { sort } = getSortingParams(MAPPINGS, types, ['type'], []); - expect(sort).toEqual([{ type: { order: undefined, unmapped_type: 'text' } }]); - }); - - it('single sort field with a single sort order', () => { - const { sort } = getSortingParams(MAPPINGS, types, ['type'], ['foo']); - expect(sort).toEqual([{ type: { order: 'foo', unmapped_type: 'text' } }]); - }); - - it('single sort field with multiple sort orders', () => { - const { sort } = getSortingParams(MAPPINGS, types, ['type'], ['foo', 'bar']); - expect(sort).toEqual([{ type: { order: 'foo', unmapped_type: 'text' } }]); - }); - - it('multiple sort fields without a sort order', () => { - const { sort } = getSortingParams(MAPPINGS, types, ['type', 'updated_at'], []); - expect(sort).toEqual([ - { type: { order: undefined, unmapped_type: 'text' } }, - { updated_at: { order: undefined, unmapped_type: 'date' } }, - ]); - }); - - it('multiple sort fields with a single sort order', () => { - const { sort } = getSortingParams(MAPPINGS, types, ['type', 'updated_at'], ['foo']); - expect(sort).toEqual([ - { type: { order: 'foo', unmapped_type: 'text' } }, - { updated_at: { order: undefined, unmapped_type: 'date' } }, - ]); + describe('sortField is simple root property with multiple types', () => { + it('returns correct params', () => { + expect(getSortingParams(MAPPINGS, ['saved', 'pending'], 'type')).toEqual({ + sort: [ + { + type: { + order: undefined, + unmapped_type: 'text', + }, + }, + ], + }); }); - - it('multiple sort fields with multiple sort orders', () => { - const { sort } = getSortingParams(MAPPINGS, types, ['type', 'updated_at'], ['foo', 'bar']); - expect(sort).toEqual([ - { type: { order: 'foo', unmapped_type: 'text' } }, - { updated_at: { order: 'bar', unmapped_type: 'date' } }, - ]); + }); + describe('sortField is simple non-root property with multiple types', () => { + it('returns correct params', () => { + expect(() => + getSortingParams(MAPPINGS, ['saved', 'pending'], 'title') + ).toThrowErrorMatchingSnapshot(); }); }); - - describe('simple properties', () => { - const types = 'saved'; - - it('single sort field without a sort order', () => { - const { sort } = getSortingParams(MAPPINGS, types, ['title'], []); - expect(sort).toEqual([{ ['saved.title']: { order: undefined, unmapped_type: 'text' } }]); + describe('sortField is multi-field with single type', () => { + it('returns correct params', () => { + expect(getSortingParams(MAPPINGS, 'saved', 'title.raw')).toEqual({ + sort: [ + { + 'saved.title.raw': { + order: undefined, + unmapped_type: 'keyword', + }, + }, + ], + }); }); - - it('single sort field with a single sort order', () => { - const { sort } = getSortingParams(MAPPINGS, types, ['title'], ['foo']); - expect(sort).toEqual([{ ['saved.title']: { order: 'foo', unmapped_type: 'text' } }]); + }); + describe('sortField is multi-field with single type as array', () => { + it('returns correct params', () => { + expect(getSortingParams(MAPPINGS, ['saved'], 'title.raw')).toEqual({ + sort: [ + { + 'saved.title.raw': { + order: undefined, + unmapped_type: 'keyword', + }, + }, + ], + }); }); - - it('single sort field with multiple sort orders', () => { - const { sort } = getSortingParams(MAPPINGS, types, ['title'], ['foo', 'bar']); - expect(sort).toEqual([{ ['saved.title']: { order: 'foo', unmapped_type: 'text' } }]); + }); + describe('sortField is root multi-field with multiple types', () => { + it('returns correct params', () => { + expect(getSortingParams(MAPPINGS, ['saved', 'pending'], 'type.raw')).toEqual({ + sort: [ + { + 'type.raw': { + order: undefined, + unmapped_type: 'keyword', + }, + }, + ], + }); }); - - it('multiple sort fields without a sort order', () => { - const { sort } = getSortingParams(MAPPINGS, types, ['title', 'obj.key1'], []); - expect(sort).toEqual([ - { ['saved.title']: { order: undefined, unmapped_type: 'text' } }, - { ['saved.obj.key1']: { order: undefined, unmapped_type: 'text' } }, - ]); + }); + describe('sortField is not-root multi-field with multiple types', () => { + it('returns correct params', () => { + expect(() => + getSortingParams(MAPPINGS, ['saved', 'pending'], 'title.raw') + ).toThrowErrorMatchingSnapshot(); }); + }); + }); - it('multiple sort fields with a single sort order', () => { - const { sort } = getSortingParams(MAPPINGS, types, ['title', 'obj.key1'], ['foo']); - expect(sort).toEqual([ - { ['saved.title']: { order: 'foo', unmapped_type: 'text' } }, - { ['saved.obj.key1']: { order: undefined, unmapped_type: 'text' } }, - ]); + describe('sort with direction', () => { + describe('sortField is simple property with single type', () => { + it('returns correct params', () => { + expect(getSortingParams(MAPPINGS, 'saved', 'title', 'desc')).toEqual({ + sort: [ + { + 'saved.title': { + order: 'desc', + unmapped_type: 'text', + }, + }, + ], + }); }); - - it('multiple sort fields with multiple sort orders', () => { - const { sort } = getSortingParams(MAPPINGS, types, ['title', 'obj.key1'], ['foo', 'bar']); - expect(sort).toEqual([ - { ['saved.title']: { order: 'foo', unmapped_type: 'text' } }, - { ['saved.obj.key1']: { order: 'bar', unmapped_type: 'text' } }, - ]); + }); + describe('sortField is root simple property with multiple type', () => { + it('returns correct params', () => { + expect(getSortingParams(MAPPINGS, ['saved', 'pending'], 'type', 'desc')).toEqual({ + sort: [ + { + type: { + order: 'desc', + unmapped_type: 'text', + }, + }, + ], + }); }); }); - - describe('mixed properties, single type', () => { - const type = 'saved'; - - it('without a sort order', () => { - const { sort } = getSortingParams(MAPPINGS, type, ['_id', 'title'], []); - expect(sort).toEqual([ - { _id: { order: undefined } }, - { ['saved.title']: { order: undefined, unmapped_type: 'text' } }, - ]); + describe('sortFields is non-root simple property with multiple types', () => { + it('returns correct params', () => { + expect(() => + getSortingParams(MAPPINGS, ['saved', 'pending'], 'title', 'desc') + ).toThrowErrorMatchingSnapshot(); }); - - it('with multiple sort orders', () => { - const { sort } = getSortingParams(MAPPINGS, type, ['_id', 'title'], ['foo', 'bar']); - expect(sort).toEqual([ - { _id: { order: 'foo' } }, - { ['saved.title']: { order: 'bar', unmapped_type: 'text' } }, - ]); + }); + describe('sortField is multi-field with single type', () => { + it('returns correct params', () => { + expect(getSortingParams(MAPPINGS, 'saved', 'title.raw', 'asc')).toEqual({ + sort: [ + { + 'saved.title.raw': { + order: 'asc', + unmapped_type: 'keyword', + }, + }, + ], + }); }); }); - - describe('mixed properties, multiple types', () => { - const types = ['saved', 'pending']; - - it('without a sort order', () => { - const { sort } = getSortingParams(MAPPINGS, types, ['_id', 'type'], []); - expect(sort).toEqual([ - { _id: { order: undefined } }, - { type: { order: undefined, unmapped_type: 'text' } }, - ]); + describe('sortField is root multi-field with multiple types', () => { + it('returns correct params', () => { + expect(getSortingParams(MAPPINGS, ['saved', 'pending'], 'type.raw', 'asc')).toEqual({ + sort: [ + { + 'type.raw': { + order: 'asc', + unmapped_type: 'keyword', + }, + }, + ], + }); }); - - it('with multiple sort orders', () => { - const { sort } = getSortingParams(MAPPINGS, types, ['_id', 'type'], ['foo', 'bar']); - expect(sort).toEqual([ - { _id: { order: 'foo' } }, - { type: { order: 'bar', unmapped_type: 'text' } }, - ]); + }); + describe('sortField is non-root multi-field with multiple types', () => { + it('returns correct params', () => { + expect(() => + getSortingParams(MAPPINGS, ['saved', 'pending'], 'title.raw', 'asc') + ).toThrowErrorMatchingSnapshot(); }); }); }); diff --git a/src/core/server/saved_objects/service/lib/search_dsl/sorting_params.ts b/src/core/server/saved_objects/service/lib/search_dsl/sorting_params.ts index ae981d45f984239..f850954e8432331 100644 --- a/src/core/server/saved_objects/service/lib/search_dsl/sorting_params.ts +++ b/src/core/server/saved_objects/service/lib/search_dsl/sorting_params.ts @@ -25,41 +25,62 @@ const TOP_LEVEL_FIELDS = ['_id', '_score']; export function getSortingParams( mappings: IndexMapping, type: string | string[], - sortFields: string[], - sortOrders: string[] + sortField?: string, + sortOrder?: string ) { - if (sortFields.length === 0) { + if (!sortField) { return {}; } const types = Array.isArray(type) ? type : [type]; - const sort = sortFields.map((sortField, i) => { - const sortOrder = sortOrders[i]; - - if (TOP_LEVEL_FIELDS.includes(sortField)) { - return { [sortField]: { order: sortOrder } }; - } + if (TOP_LEVEL_FIELDS.includes(sortField)) { + return { + sort: [ + { + [sortField]: { + order: sortOrder, + }, + }, + ], + }; + } - if (types.length > 1) { - const rootField = getProperty(mappings, sortField); - if (!rootField) { - throw Boom.badRequest( - `Unable to sort multiple types by field ${sortField}, not a root property` - ); - } - return { [sortField]: { order: sortOrder, unmapped_type: rootField.type } }; + if (types.length > 1) { + const rootField = getProperty(mappings, sortField); + if (!rootField) { + throw Boom.badRequest( + `Unable to sort multiple types by field ${sortField}, not a root property` + ); } - const [typeField] = types; - const key = `${typeField}.${sortField}`; - const field = getProperty(mappings, key); - if (!field) { - throw Boom.badRequest(`Unknown sort field ${sortField}`); - } + return { + sort: [ + { + [sortField]: { + order: sortOrder, + unmapped_type: rootField.type, + }, + }, + ], + }; + } - return { [key]: { order: sortOrder, unmapped_type: field.type } }; - }); + const [typeField] = types; + const key = `${typeField}.${sortField}`; + const field = getProperty(mappings, key); + if (!field) { + throw Boom.badRequest(`Unknown sort field ${sortField}`); + } - return { sort }; + return { + sort: [ + { + [key]: { + order: sortOrder, + unmapped_type: field.type, + }, + }, + ], + }; } diff --git a/src/core/server/saved_objects/types.ts b/src/core/server/saved_objects/types.ts index aeca527e4367275..92e33bd5bac51db 100644 --- a/src/core/server/saved_objects/types.ts +++ b/src/core/server/saved_objects/types.ts @@ -70,8 +70,8 @@ export interface SavedObjectsFindOptions extends SavedObjectsBaseOptions { type: string | string[]; page?: number; perPage?: number; - sortField?: string | string[]; - sortOrder?: string | string[]; + sortField?: string; + sortOrder?: string; /** * An array of fields to include in the results * @example diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 3369db2b24e805a..daa3b2da9f9876e 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -2205,9 +2205,9 @@ export interface SavedObjectsFindOptions extends SavedObjectsBaseOptions { search?: string; searchFields?: string[]; // (undocumented) - sortField?: string | string[]; + sortField?: string; // (undocumented) - sortOrder?: string | string[]; + sortOrder?: string; // (undocumented) type: string | string[]; } diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.tsx b/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.tsx index 6cd0c891c2247f4..38b618fb082b916 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.tsx +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.tsx @@ -224,9 +224,7 @@ export class SavedObjectsTable extends Component !visibleTypes || visibleTypes.includes(type)), }; if (findOptions.type.length > 1) { - findOptions.sortField = ['type', '_id']; - } else { - findOptions.sortField = '_id'; + findOptions.sortField = 'type'; } try { diff --git a/src/plugins/saved_objects_management/server/routes/find.ts b/src/plugins/saved_objects_management/server/routes/find.ts index 2bb7a692eefcb15..0d88e6ec3f3b588 100644 --- a/src/plugins/saved_objects_management/server/routes/find.ts +++ b/src/plugins/saved_objects_management/server/routes/find.ts @@ -38,7 +38,7 @@ export const registerFindRoute = ( defaultSearchOperator: schema.oneOf([schema.literal('OR'), schema.literal('AND')], { defaultValue: 'OR', }), - sortField: schema.maybe(schema.oneOf([schema.string(), schema.arrayOf(schema.string())])), + sortField: schema.maybe(schema.string()), hasReference: schema.maybe( schema.object({ type: schema.string(),