Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SearchSource] Combine sort and parent fields when serializing #89808

Merged
merged 7 commits into from
Feb 2, 2021
Merged
Show file tree
Hide file tree
Changes from 3 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 @@ -9,45 +9,16 @@ returns all search source fields
<b>Signature:</b>

```typescript
getFields(): {
type?: string | undefined;
query?: import("../..").Query | undefined;
filter?: Filter | Filter[] | (() => Filter | Filter[] | undefined) | undefined;
sort?: Record<string, import("./types").SortDirectionNumeric | import("./types").SortDirection> | Record<string, import("./types").SortDirectionNumeric | import("./types").SortDirection>[] | undefined;
highlight?: any;
highlightAll?: boolean | undefined;
aggs?: any;
from?: number | undefined;
size?: number | undefined;
source?: string | boolean | string[] | undefined;
version?: boolean | undefined;
fields?: SearchFieldValue[] | undefined;
fieldsFromSource?: string | boolean | string[] | undefined;
index?: import("../..").IndexPattern | undefined;
searchAfter?: import("./types").EsQuerySearchAfter | undefined;
timeout?: string | undefined;
terminate_after?: number | undefined;
};
getFields(recurse?: boolean): SearchSourceFields;
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| recurse | <code>boolean</code> | |

<b>Returns:</b>

`{
type?: string | undefined;
query?: import("../..").Query | undefined;
filter?: Filter | Filter[] | (() => Filter | Filter[] | undefined) | undefined;
sort?: Record<string, import("./types").SortDirectionNumeric | import("./types").SortDirection> | Record<string, import("./types").SortDirectionNumeric | import("./types").SortDirection>[] | undefined;
highlight?: any;
highlightAll?: boolean | undefined;
aggs?: any;
from?: number | undefined;
size?: number | undefined;
source?: string | boolean | string[] | undefined;
version?: boolean | undefined;
fields?: SearchFieldValue[] | undefined;
fieldsFromSource?: string | boolean | string[] | undefined;
index?: import("../..").IndexPattern | undefined;
searchAfter?: import("./types").EsQuerySearchAfter | undefined;
timeout?: string | undefined;
terminate_after?: number | undefined;
}`
`SearchSourceFields`

Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,15 @@ serializes search source fields (which can later be passed to [ISearchStartSearc
<b>Signature:</b>

```typescript
getSerializedFields(): SearchSourceFields;
getSerializedFields(recurse?: boolean): SearchSourceFields;
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| recurse | <code>boolean</code> | |

<b>Returns:</b>

`SearchSourceFields`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ export declare class SearchSource
| [fetch(options)](./kibana-plugin-plugins-data-public.searchsource.fetch.md) | | Fetch this source and reject the returned Promise on error |
| [fetch$(options)](./kibana-plugin-plugins-data-public.searchsource.fetch_.md) | | Fetch this source from Elasticsearch, returning an observable over the response(s) |
| [getField(field, recurse)](./kibana-plugin-plugins-data-public.searchsource.getfield.md) | | Gets a single field from the fields |
| [getFields()](./kibana-plugin-plugins-data-public.searchsource.getfields.md) | | returns all search source fields |
| [getFields(recurse)](./kibana-plugin-plugins-data-public.searchsource.getfields.md) | | returns all search source fields |
| [getId()](./kibana-plugin-plugins-data-public.searchsource.getid.md) | | returns search source id |
| [getOwnField(field)](./kibana-plugin-plugins-data-public.searchsource.getownfield.md) | | Get the field from our own fields, don't traverse up the chain |
| [getParent()](./kibana-plugin-plugins-data-public.searchsource.getparent.md) | | Get the parent of this SearchSource {<!-- -->undefined\|searchSource<!-- -->} |
| [getSearchRequestBody()](./kibana-plugin-plugins-data-public.searchsource.getsearchrequestbody.md) | | Returns body contents of the search request, often referred as query DSL. |
| [getSerializedFields()](./kibana-plugin-plugins-data-public.searchsource.getserializedfields.md) | | serializes search source fields (which can later be passed to [ISearchStartSearchSource](./kibana-plugin-plugins-data-public.isearchstartsearchsource.md)<!-- -->) |
| [getSerializedFields(recurse)](./kibana-plugin-plugins-data-public.searchsource.getserializedfields.md) | | serializes search source fields (which can later be passed to [ISearchStartSearchSource](./kibana-plugin-plugins-data-public.isearchstartsearchsource.md)<!-- -->) |
| [onRequestStart(handler)](./kibana-plugin-plugins-data-public.searchsource.onrequeststart.md) | | Add a handler that will be notified whenever requests start |
| [removeField(field)](./kibana-plugin-plugins-data-public.searchsource.removefield.md) | | remove field |
| [serialize()](./kibana-plugin-plugins-data-public.searchsource.serialize.md) | | Serializes the instance to a JSON string and a set of referenced objects. Use this method to get a representation of the search source which can be stored in a saved object.<!-- -->The references returned by this function can be mixed with other references in the same object, however make sure there are no name-collisions. The references will be named <code>kibanaSavedObjectMeta.searchSourceJSON.index</code> and <code>kibanaSavedObjectMeta.searchSourceJSON.filter[&lt;number&gt;].meta.index</code>.<!-- -->Using <code>createSearchSource</code>, the instance can be re-created. |
Expand Down
16 changes: 15 additions & 1 deletion src/plugins/data/common/field_formats/field_formats_registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,28 @@ import { FormatFactory } from './utils';
import { ES_FIELD_TYPES, KBN_FIELD_TYPES } from '../kbn_field_types/types';
import { UI_SETTINGS } from '../constants';
import { FieldFormatNotFoundError } from '../field_formats';
import { SerializedFieldFormat } from '../../../expressions/common/types';

export class FieldFormatsRegistry {
protected fieldFormats: Map<FieldFormatId, FieldFormatInstanceType> = new Map();
protected defaultMap: Record<string, FieldFormatConfig> = {};
protected metaParamsOptions: Record<string, any> = {};
protected getConfig?: FieldFormatsGetConfigFn;
// overriden on the public contract
public deserialize: FormatFactory = () => {
public deserialize: FormatFactory = (mapping?: SerializedFieldFormat) => {
if (!mapping) {
return new (FieldFormat.from(identity))();
}

const { id, params = {} } = mapping;
if (id) {
const Format = this.getType(id);

if (Format) {
return new Format(params, this.getConfig);
}
}

return new (FieldFormat.from(identity))();
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ function normalize(
}
}

// FIXME: for unknown reason on the server this setting is serialized
Copy link
Member

Choose a reason for hiding this comment

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

can we create an issue for this and link it here ?

Copy link
Member Author

Choose a reason for hiding this comment

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

if (typeof defaultSortOptions === 'string') {
defaultSortOptions = JSON.parse(defaultSortOptions);
}
// Don't include unmapped_type for _score field
// eslint-disable-next-line @typescript-eslint/naming-convention
const { unmapped_type, ...otherSortOptions } = defaultSortOptions;
Expand Down
119 changes: 117 additions & 2 deletions src/plugins/data/common/search/search_source/search_source.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,121 @@ describe('SearchSource', () => {
});
});

describe('#getFields()', () => {
test('gets the value for the property', () => {
searchSource.setField('aggs', 5);
expect(searchSource.getFields()).toMatchInlineSnapshot(`
Object {
"aggs": 5,
}
`);
});

test('recurses parents to get the entire filters: plain object filter', () => {
const RECURSE = true;

const parent = new SearchSource({}, searchSourceDependencies);
parent.setField('filter', [
{
meta: {
index: 'd180cae0-60c3-11eb-8569-bd1f5ed24bc9',
params: {},
alias: null,
disabled: false,
negate: false,
},
query: {
range: {
'@date': {
gte: '2016-01-27T18:11:05.010Z',
lte: '2021-01-27T18:11:05.010Z',
format: 'strict_date_optional_time',
},
},
},
},
]);
searchSource.setParent(parent);
searchSource.setField('aggs', 5);
expect(searchSource.getFields(RECURSE)).toMatchInlineSnapshot(`
Object {
"aggs": 5,
"filter": Array [
Object {
"meta": Object {
"alias": null,
"disabled": false,
"index": "d180cae0-60c3-11eb-8569-bd1f5ed24bc9",
"negate": false,
"params": Object {},
},
"query": Object {
"range": Object {
"@date": Object {
"format": "strict_date_optional_time",
"gte": "2016-01-27T18:11:05.010Z",
"lte": "2021-01-27T18:11:05.010Z",
},
},
},
},
],
}
`);
});

test('recurses parents to get the entire filters: function filter', () => {
const RECURSE = true;

const parent = new SearchSource({}, searchSourceDependencies);
parent.setField('filter', () => ({
meta: {
index: 'd180cae0-60c3-11eb-8569-bd1f5ed24bc9',
params: {},
alias: null,
disabled: false,
negate: false,
},
query: {
range: {
'@date': {
gte: '2016-01-27T18:11:05.010Z',
lte: '2021-01-27T18:11:05.010Z',
format: 'strict_date_optional_time',
},
},
},
}));
searchSource.setParent(parent);
searchSource.setField('aggs', 5);
expect(searchSource.getFields(RECURSE)).toMatchInlineSnapshot(`
Object {
"aggs": 5,
"filter": Array [
Object {
"meta": Object {
"alias": null,
"disabled": false,
"index": "d180cae0-60c3-11eb-8569-bd1f5ed24bc9",
"negate": false,
"params": Object {},
},
"query": Object {
"range": Object {
"@date": Object {
"format": "strict_date_optional_time",
"gte": "2016-01-27T18:11:05.010Z",
"lte": "2021-01-27T18:11:05.010Z",
},
},
},
},
],
}
`);
});
});

describe('#removeField()', () => {
test('remove property', () => {
searchSource = new SearchSource({}, searchSourceDependencies);
Expand Down Expand Up @@ -619,13 +734,13 @@ describe('SearchSource', () => {
expect(JSON.parse(searchSourceJSON).from).toEqual(123456);
});

test('should omit sort and size', () => {
test('should omit size but not sort', () => {
searchSource.setField('highlightAll', true);
searchSource.setField('from', 123456);
searchSource.setField('sort', { field: SortDirection.asc });
searchSource.setField('size', 200);
const { searchSourceJSON } = searchSource.serialize();
expect(Object.keys(JSON.parse(searchSourceJSON))).toEqual(['highlightAll', 'from']);
expect(Object.keys(JSON.parse(searchSourceJSON))).toEqual(['highlightAll', 'from', 'sort']);
});

test('should serialize filters', () => {
Expand Down
46 changes: 42 additions & 4 deletions src/plugins/data/common/search/search_source/search_source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,46 @@ export class SearchSource {
/**
* returns all search source fields
*/
getFields() {
getFields(recurse = false): SearchSourceFields {
let thisFilter = this.fields.filter; // type is single value, array, or function
if (thisFilter) {
if (typeof thisFilter === 'function') {
thisFilter = thisFilter() || []; // type is single value or array
}

if (Array.isArray(thisFilter)) {
thisFilter = [...thisFilter];
} else {
thisFilter = [thisFilter];
}
} else {
thisFilter = [];
}

if (recurse) {
const parent = this.getParent();
if (parent) {
const parentFields = parent.getFields(recurse);

let parentFilter = parentFields.filter; // type is single value, array, or function
if (parentFilter) {
if (typeof parentFilter === 'function') {
parentFilter = parentFilter() || []; // type is single value or array
}

if (Array.isArray(parentFilter)) {
thisFilter.push(...parentFilter);
} else {
thisFilter.push(parentFilter);
}
}

// set filter to the array of non-function-type filters
this.setField('filter', thisFilter);

return { ...parentFields, ...this.fields };
}
}
return { ...this.fields };
}

Expand Down Expand Up @@ -605,9 +644,8 @@ export class SearchSource {
/**
* serializes search source fields (which can later be passed to {@link ISearchStartSearchSource})
*/
public getSerializedFields() {
const { filter: originalFilters, ...searchSourceFields } = omit(this.getFields(), [
'sort',
public getSerializedFields(recurse = false) {
const { filter: originalFilters, ...searchSourceFields } = omit(this.getFields(recurse), [
'size',
]);
let serializedSearchSourceFields: SearchSourceFields = {
Expand Down
Loading