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 50b28b1ba0a2372..ebd0a99531755b2 100644
--- a/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.md
+++ b/docs/development/core/public/kibana-plugin-core-public.savedobjectsfindoptions.md
@@ -26,7 +26,7 @@ export interface SavedObjectsFindOptions
| [rootSearchFields](./kibana-plugin-core-public.savedobjectsfindoptions.rootsearchfields.md) | string[]
| The fields to perform the parsed query against. Unlike the searchFields
argument, these are expected to be root fields 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 82225607a7955ef..15a9d99b3d062e7 100644
--- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.md
+++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsfindoptions.md
@@ -26,7 +26,7 @@ export interface SavedObjectsFindOptions
| [rootSearchFields](./kibana-plugin-core-server.savedobjectsfindoptions.rootsearchfields.md) | string[]
| The fields to perform the parsed query against. Unlike the searchFields
argument, these are expected to be root fields 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 79a822b2736567e..e8a28c897b014b7 100644
--- a/src/core/public/public.api.md
+++ b/src/core/public/public.api.md
@@ -1316,9 +1316,9 @@ export interface SavedObjectsFindOptions {
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 4787a227438b1c6..62e629ad33cc884 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 f0fb25abb8e094a..ddf20606800c8ee 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[];
rootSearchFields?: string[];
- sortField?: string | string[];
- sortOrder?: string | string[];
+ sortField?: string;
+ sortOrder?: string;
namespaces?: 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 8cd8e8a12d97184..7b3697173ef0da7 100644
--- a/src/core/server/saved_objects/types.ts
+++ b/src/core/server/saved_objects/types.ts
@@ -70,8 +70,8 @@ export interface SavedObjectsFindOptions {
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 2c82c4d875a8b35..cb651043844c2ce 100644
--- a/src/core/server/server.api.md
+++ b/src/core/server/server.api.md
@@ -2219,9 +2219,9 @@ export interface SavedObjectsFindOptions {
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(),