Skip to content

Commit 3e33df1

Browse files
authored
[Data views as code] Add field filters to saved schema (elastic#270538)
## Summary Related to elastic#262225 Field filters can be used to exclude fields when fetching a document. In the original as code saved data view object it wasn't added, but it should. ### Checklist Check the PR satisfies following conditions. Reviewers should verify this PR satisfies this list as well. - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [x] The PR description includes the appropriate Release Notes section, and the correct `release_note:*` label is applied per the [guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) - [x] Review the [backport guidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing) and apply applicable `backport:*` labels.
1 parent 1be5b19 commit 3e33df1

6 files changed

Lines changed: 117 additions & 1 deletion

File tree

src/platform/packages/shared/as-code/data-views-schema/src/data_views/schema_saved_data_view.test.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,41 @@ describe('savedDataViewSpecSchema', () => {
8080
);
8181
});
8282

83+
it('accepts field_filters as an array of strings', () => {
84+
const input = {
85+
index_pattern: 'logs-*',
86+
field_filters: ['field_a', 'field_b'],
87+
};
88+
89+
expect(savedDataViewSpecSchema.validate(input)).toEqual(input);
90+
});
91+
92+
it('accepts an empty field_filters array', () => {
93+
const input = {
94+
index_pattern: 'logs-*',
95+
field_filters: [],
96+
};
97+
98+
expect(savedDataViewSpecSchema.validate(input)).toEqual(input);
99+
});
100+
101+
it('accepts spec without field_filters', () => {
102+
const input = {
103+
index_pattern: 'logs-*',
104+
};
105+
106+
expect(savedDataViewSpecSchema.validate(input)).toEqual(input);
107+
});
108+
109+
it('rejects field_filters with non-string values', () => {
110+
const input = {
111+
index_pattern: 'logs-*',
112+
field_filters: [123],
113+
};
114+
115+
expect(() => savedDataViewSpecSchema.validate(input)).toThrow();
116+
});
117+
83118
it('rejects an empty field_settings key', () => {
84119
const input = {
85120
index_pattern: 'logs-*',

src/platform/packages/shared/as-code/data-views-schema/src/data_views/schema_saved_data_view.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,16 @@ export const savedDataViewSpecSchema = schema.object(
6262
},
6363
})
6464
),
65+
field_filters: schema.maybe(
66+
schema.arrayOf(schema.string({ minLength: 1, maxLength: 1000 }), {
67+
maxSize: 10_000,
68+
meta: {
69+
title: 'Field filters',
70+
description:
71+
"Field filters can be used to exclude one or more fields when fetching a document. They may contain wildcards, such as `user*` which filters fields starting with 'user'.",
72+
},
73+
})
74+
),
6575
index_pattern: indexPatternSchema,
6676
time_field: timeFieldSchema,
6777
field_settings: schema.maybe(

src/platform/packages/shared/as-code/data-views-transforms/src/from_stored_data_view.test.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,4 +161,34 @@ describe('fromStoredDataViewToAsCodeSavedSchema', () => {
161161
},
162162
});
163163
});
164+
165+
it('maps sourceFilters to field_filters', () => {
166+
expect(
167+
fromStoredDataViewToAsCodeSavedSchema({
168+
title: 'logs-*',
169+
sourceFilters: [{ value: 'field_a' }, { value: 'field_b' }],
170+
})
171+
).toEqual(
172+
expect.objectContaining({
173+
field_filters: ['field_a', 'field_b'],
174+
})
175+
);
176+
});
177+
178+
it('omits field_filters when sourceFilters is empty', () => {
179+
const result = fromStoredDataViewToAsCodeSavedSchema({
180+
title: 'logs-*',
181+
sourceFilters: [],
182+
});
183+
184+
expect(result).not.toHaveProperty('field_filters');
185+
});
186+
187+
it('omits field_filters when sourceFilters is absent', () => {
188+
const result = fromStoredDataViewToAsCodeSavedSchema({
189+
title: 'logs-*',
190+
});
191+
192+
expect(result).not.toHaveProperty('field_filters');
193+
});
164194
});

src/platform/packages/shared/as-code/data-views-transforms/src/from_stored_data_view.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,5 +61,9 @@ export function fromStoredDataViewToAsCodeSavedSchema(index: DataViewSpec): AsCo
6161
time_field: index.timeFieldName,
6262
allow_hidden_indices: index.allowHidden,
6363
field_settings: fieldSettings,
64+
...(index.sourceFilters &&
65+
index.sourceFilters.length > 0 && {
66+
field_filters: index.sourceFilters.map((sourceFilter) => sourceFilter.value),
67+
}),
6468
};
6569
}

src/platform/packages/shared/as-code/data-views-transforms/src/to_stored_data_view.test.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
type AsCodeSavedDataView,
1616
} from '@kbn/as-code-data-views-schema';
1717
import { toStoredDataView } from './to_stored_data_view';
18+
import type { DataViewSpec } from '@kbn/data-views-plugin/common';
1819

1920
describe('toStoredDataView', () => {
2021
it('converts data_view_reference data_source to string id', () => {
@@ -154,5 +155,35 @@ describe('toStoredDataView', () => {
154155
},
155156
});
156157
});
158+
159+
it('maps field_filters to sourceFilters', () => {
160+
const dataView: AsCodeSavedDataView = {
161+
id: 'dv-1',
162+
index_pattern: 'logs-*',
163+
field_filters: ['field_a', 'field_b'],
164+
};
165+
166+
const result = toStoredDataView(dataView);
167+
expect(result).toEqual(
168+
expect.objectContaining({
169+
sourceFilters: [{ value: 'field_a' }, { value: 'field_b' }],
170+
})
171+
);
172+
});
173+
174+
it('omits sourceFilters when field_filters is undefined', () => {
175+
const dataView: AsCodeSavedDataView = {
176+
id: 'dv-2',
177+
index_pattern: 'logs-*',
178+
};
179+
180+
const result = toStoredDataView(dataView);
181+
expect(result).toEqual(
182+
expect.objectContaining({
183+
title: 'logs-*',
184+
})
185+
);
186+
expect((result as DataViewSpec).sourceFilters).toBeUndefined();
187+
});
157188
});
158189
});

src/platform/packages/shared/as-code/data-views-transforms/src/to_stored_data_view.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,12 @@ export function toStoredDataView(
4949
function isSavedDataView(
5050
dataView: AsCodeDataView | AsCodeSavedDataView
5151
): dataView is AsCodeSavedDataView {
52-
return 'id' in dataView || 'name' in dataView || 'allow_hidden_indices' in dataView;
52+
return (
53+
'id' in dataView ||
54+
'name' in dataView ||
55+
'allow_hidden_indices' in dataView ||
56+
'field_filters' in dataView
57+
);
5358
}
5459

5560
function getSavedDataViewFields(dataView: AsCodeSavedDataView): Partial<DataViewSpec> {
@@ -58,5 +63,6 @@ function getSavedDataViewFields(dataView: AsCodeSavedDataView): Partial<DataView
5863
id: dataView.id,
5964
name: dataView.name,
6065
allowHidden: dataView.allow_hidden_indices,
66+
sourceFilters: dataView.field_filters?.map((filter) => ({ value: filter })),
6167
};
6268
}

0 commit comments

Comments
 (0)