Skip to content

Commit

Permalink
support serializing nested searchsource (#91525)
Browse files Browse the repository at this point in the history
  • Loading branch information
ppisljar authored Feb 18, 2021
1 parent dadf0e6 commit 7503fd2
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 216 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,8 @@ returns all search source fields
<b>Signature:</b>

```typescript
getFields(recurse?: boolean): SearchSourceFields;
getFields(): 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,7 +35,7 @@ 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(recurse)](./kibana-plugin-plugins-data-public.searchsource.getfields.md) | | returns all search source fields |
| [getFields()](./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<!-- -->} |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export interface SearchSourceFields
| [highlight](./kibana-plugin-plugins-data-public.searchsourcefields.highlight.md) | <code>any</code> | |
| [highlightAll](./kibana-plugin-plugins-data-public.searchsourcefields.highlightall.md) | <code>boolean</code> | |
| [index](./kibana-plugin-plugins-data-public.searchsourcefields.index.md) | <code>IndexPattern</code> | |
| [parent](./kibana-plugin-plugins-data-public.searchsourcefields.parent.md) | <code>SearchSourceFields</code> | |
| [query](./kibana-plugin-plugins-data-public.searchsourcefields.query.md) | <code>Query</code> | [Query](./kibana-plugin-plugins-data-public.query.md) |
| [searchAfter](./kibana-plugin-plugins-data-public.searchsourcefields.searchafter.md) | <code>EsQuerySearchAfter</code> | |
| [size](./kibana-plugin-plugins-data-public.searchsourcefields.size.md) | <code>number</code> | |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) &gt; [SearchSourceFields](./kibana-plugin-plugins-data-public.searchsourcefields.md) &gt; [parent](./kibana-plugin-plugins-data-public.searchsourcefields.parent.md)

## SearchSourceFields.parent property

<b>Signature:</b>

```typescript
parent?: SearchSourceFields;
```
228 changes: 70 additions & 158 deletions src/plugins/data/common/search/search_source/search_source.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,164 +95,6 @@ describe('SearchSource', () => {
}
`);
});

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",
},
},
},
},
],
}
`);

// calling twice gives the same result: no searchSources in the hierarchy were modified
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",
},
},
},
},
],
}
`);

// calling twice gives the same result: no double-added filters
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()', () => {
Expand Down Expand Up @@ -975,4 +817,74 @@ describe('SearchSource', () => {
expect(request._source).toEqual(['geometry']);
});
});

describe('getSerializedFields', () => {
const filter = [
{
query: 'query',
meta: {
alias: 'alias',
disabled: false,
negate: false,
index: '456',
},
},
];

test('should return serialized fields', () => {
const indexPattern123 = { id: '123' } as IndexPattern;
searchSource.setField('index', indexPattern123);
searchSource.setField('filter', () => {
return filter;
});
const serializedFields = searchSource.getSerializedFields();
expect(serializedFields).toMatchInlineSnapshot(
{ index: '123', filter },
`
Object {
"filter": Array [
Object {
"meta": Object {
"alias": "alias",
"disabled": false,
"index": "456",
"negate": false,
},
"query": "query",
},
],
"index": "123",
}
`
);
});

test('should support nested search sources', () => {
const indexPattern123 = { id: '123' } as IndexPattern;
searchSource.setField('index', indexPattern123);
searchSource.setField('from', 123);
const childSearchSource = searchSource.createChild();
childSearchSource.setField('timeout', '100');
const serializedFields = childSearchSource.getSerializedFields(true);
expect(serializedFields).toMatchInlineSnapshot(
{
timeout: '100',
parent: {
index: '123',
from: 123,
},
},
`
Object {
"index": undefined,
"parent": Object {
"from": 123,
"index": "123",
},
"timeout": "100",
}
`
);
});
});
});
60 changes: 12 additions & 48 deletions src/plugins/data/common/search/search_source/search_source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
*/

import { setWith } from '@elastic/safer-lodash-set';
import { uniqueId, keyBy, pick, difference, omit, isFunction, isEqual, uniqWith } from 'lodash';
import { uniqueId, keyBy, pick, difference, isFunction, isEqual, uniqWith } from 'lodash';
import { map, switchMap, tap } from 'rxjs/operators';
import { defer, from } from 'rxjs';
import { isObject } from 'rxjs/internal-compatibility';
Expand Down Expand Up @@ -114,8 +114,13 @@ export class SearchSource {
private readonly dependencies: SearchSourceDependencies;

constructor(fields: SearchSourceFields = {}, dependencies: SearchSourceDependencies) {
this.fields = fields;
const { parent, ...currentFields } = fields;
this.fields = currentFields;
this.dependencies = dependencies;

if (parent) {
this.setParent(new SearchSource(parent, dependencies));
}
}

/** ***
Expand Down Expand Up @@ -173,49 +178,7 @@ export class SearchSource {
/**
* returns all search source fields
*/
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);
}
}

// add combined filters to the fields
const thisFields = {
...this.fields,
filter: thisFilter,
};

return { ...parentFields, ...thisFields };
}
}
getFields(): SearchSourceFields {
return { ...this.fields };
}

Expand Down Expand Up @@ -727,9 +690,7 @@ export class SearchSource {
* serializes search source fields (which can later be passed to {@link ISearchStartSearchSource})
*/
public getSerializedFields(recurse = false) {
const { filter: originalFilters, ...searchSourceFields } = omit(this.getFields(recurse), [
'size',
]);
const { filter: originalFilters, size: omit, ...searchSourceFields } = this.getFields();
let serializedSearchSourceFields: SearchSourceFields = {
...searchSourceFields,
index: (searchSourceFields.index ? searchSourceFields.index.id : undefined) as any,
Expand All @@ -741,6 +702,9 @@ export class SearchSource {
filter: filters,
};
}
if (recurse && this.getParent()) {
serializedSearchSourceFields.parent = this.getParent()!.getSerializedFields(recurse);
}
return serializedSearchSourceFields;
}

Expand Down
2 changes: 2 additions & 0 deletions src/plugins/data/common/search/search_source/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ export interface SearchSourceFields {
searchAfter?: EsQuerySearchAfter;
timeout?: string;
terminate_after?: number;

parent?: SearchSourceFields;
}

export interface SearchSourceOptions {
Expand Down
Loading

0 comments on commit 7503fd2

Please sign in to comment.