Skip to content

Commit

Permalink
[7.17] [Discover/CSV Reporting] Fix support for nested field columns …
Browse files Browse the repository at this point in the history
…in CSV reports (#172240) (#172336)

# Backport

This will backport the following commits from `main` to `7.17`:
- [[Discover/CSV Reporting] Fix support for nested field columns in CSV
reports (#172240)](#172240)

<!--- Backport version: 8.9.8 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Davis
McPhee","email":"[email protected]"},"sourceCommit":{"committedDate":"2023-11-30T16:43:39Z","message":"[Discover/CSV
Reporting] Fix support for nested field columns in CSV reports
(#172240)\n\n## Summary\r\n\r\nWhen we generate the parameters for the
report, we add all of the\r\nselected columns as entries in the search
request `fields` array (or `*`\r\nif none are selected, which is why
this case works), but this doesn't\r\nwork for nested fields since [the
fields API doesn't support
nested\r\nfield\r\nroots](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-fields.html#search-fields-nested):\r\n>However,
when the `fields` pattern targets the nested `user` field\r\ndirectly,
no values will be returned because the pattern doesn’t match\r\nany leaf
fields.\r\n\r\nInstead we can detect nested fields and add them to the
`fields` array\r\nas `{nestedFieldName}.*`, ensuring that all of the
leaf fields are\r\nreturned in the response.\r\n\r\nFixes
#172236.\r\n\r\n### Checklist\r\n\r\n- [ ] Any text added follows [EUI's
writing\r\nguidelines](https://elastic.github.io/eui/#/guidelines/writing),
uses\r\nsentence case text and includes
[i18n\r\nsupport](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)\r\n-
[
]\r\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\r\nwas
added for features that require explanation or tutorials\r\n- [x] [Unit
or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common scenarios\r\n- [ ] Any UI
touched in this PR is usable by keyboard only (learn more\r\nabout
[keyboard accessibility](https://webaim.org/techniques/keyboard/))\r\n-
[ ] Any UI touched in this PR does not create any new axe
failures\r\n(run axe in
browser:\r\n[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),\r\n[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))\r\n-
[ ] If a plugin configuration key changed, check if it needs to
be\r\nallowlisted in the cloud and added to the
[docker\r\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)\r\n-
[ ] This renders correctly on smaller devices using a
responsive\r\nlayout. (You can test this [in
your\r\nbrowser](https://www.browserstack.com/guide/responsive-testing-on-local-server))\r\n-
[ ] This was checked for
[cross-browser\r\ncompatibility](https://www.elastic.co/support/matrix#matrix_browsers)\r\n\r\n###
For maintainers\r\n\r\n- [ ] This was checked for breaking API changes
and was
[labeled\r\nappropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<[email protected]>","sha":"ab5ff9ca626baa90c3cc0e92813ff70cb5956e23","branchLabelMapping":{"^v8.12.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix","Team:DataDiscovery","backport:prev-minor","backport:prev-MAJOR","v8.12.0"],"number":172240,"url":"https://github.com/elastic/kibana/pull/172240","mergeCommit":{"message":"[Discover/CSV
Reporting] Fix support for nested field columns in CSV reports
(#172240)\n\n## Summary\r\n\r\nWhen we generate the parameters for the
report, we add all of the\r\nselected columns as entries in the search
request `fields` array (or `*`\r\nif none are selected, which is why
this case works), but this doesn't\r\nwork for nested fields since [the
fields API doesn't support
nested\r\nfield\r\nroots](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-fields.html#search-fields-nested):\r\n>However,
when the `fields` pattern targets the nested `user` field\r\ndirectly,
no values will be returned because the pattern doesn’t match\r\nany leaf
fields.\r\n\r\nInstead we can detect nested fields and add them to the
`fields` array\r\nas `{nestedFieldName}.*`, ensuring that all of the
leaf fields are\r\nreturned in the response.\r\n\r\nFixes
#172236.\r\n\r\n### Checklist\r\n\r\n- [ ] Any text added follows [EUI's
writing\r\nguidelines](https://elastic.github.io/eui/#/guidelines/writing),
uses\r\nsentence case text and includes
[i18n\r\nsupport](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)\r\n-
[
]\r\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\r\nwas
added for features that require explanation or tutorials\r\n- [x] [Unit
or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common scenarios\r\n- [ ] Any UI
touched in this PR is usable by keyboard only (learn more\r\nabout
[keyboard accessibility](https://webaim.org/techniques/keyboard/))\r\n-
[ ] Any UI touched in this PR does not create any new axe
failures\r\n(run axe in
browser:\r\n[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),\r\n[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))\r\n-
[ ] If a plugin configuration key changed, check if it needs to
be\r\nallowlisted in the cloud and added to the
[docker\r\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)\r\n-
[ ] This renders correctly on smaller devices using a
responsive\r\nlayout. (You can test this [in
your\r\nbrowser](https://www.browserstack.com/guide/responsive-testing-on-local-server))\r\n-
[ ] This was checked for
[cross-browser\r\ncompatibility](https://www.elastic.co/support/matrix#matrix_browsers)\r\n\r\n###
For maintainers\r\n\r\n- [ ] This was checked for breaking API changes
and was
[labeled\r\nappropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<[email protected]>","sha":"ab5ff9ca626baa90c3cc0e92813ff70cb5956e23"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v8.12.0","labelRegex":"^v8.12.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/172240","number":172240,"mergeCommit":{"message":"[Discover/CSV
Reporting] Fix support for nested field columns in CSV reports
(#172240)\n\n## Summary\r\n\r\nWhen we generate the parameters for the
report, we add all of the\r\nselected columns as entries in the search
request `fields` array (or `*`\r\nif none are selected, which is why
this case works), but this doesn't\r\nwork for nested fields since [the
fields API doesn't support
nested\r\nfield\r\nroots](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-fields.html#search-fields-nested):\r\n>However,
when the `fields` pattern targets the nested `user` field\r\ndirectly,
no values will be returned because the pattern doesn’t match\r\nany leaf
fields.\r\n\r\nInstead we can detect nested fields and add them to the
`fields` array\r\nas `{nestedFieldName}.*`, ensuring that all of the
leaf fields are\r\nreturned in the response.\r\n\r\nFixes
#172236.\r\n\r\n### Checklist\r\n\r\n- [ ] Any text added follows [EUI's
writing\r\nguidelines](https://elastic.github.io/eui/#/guidelines/writing),
uses\r\nsentence case text and includes
[i18n\r\nsupport](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)\r\n-
[
]\r\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\r\nwas
added for features that require explanation or tutorials\r\n- [x] [Unit
or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common scenarios\r\n- [ ] Any UI
touched in this PR is usable by keyboard only (learn more\r\nabout
[keyboard accessibility](https://webaim.org/techniques/keyboard/))\r\n-
[ ] Any UI touched in this PR does not create any new axe
failures\r\n(run axe in
browser:\r\n[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),\r\n[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))\r\n-
[ ] If a plugin configuration key changed, check if it needs to
be\r\nallowlisted in the cloud and added to the
[docker\r\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)\r\n-
[ ] This renders correctly on smaller devices using a
responsive\r\nlayout. (You can test this [in
your\r\nbrowser](https://www.browserstack.com/guide/responsive-testing-on-local-server))\r\n-
[ ] This was checked for
[cross-browser\r\ncompatibility](https://www.elastic.co/support/matrix#matrix_browsers)\r\n\r\n###
For maintainers\r\n\r\n- [ ] This was checked for breaking API changes
and was
[labeled\r\nappropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<[email protected]>","sha":"ab5ff9ca626baa90c3cc0e92813ff70cb5956e23"}},{"url":"https://github.com/elastic/kibana/pull/172335","number":172335,"branch":"8.11","state":"OPEN"}]}]
BACKPORT-->
  • Loading branch information
davismcphee authored Dec 1, 2023
1 parent 94b0573 commit 7a29ee9
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,43 @@ describe('getSharingData', () => {
]);
});

test('getSearchSource supports nested fields', async () => {
const fields = [
...indexPatternMock.fields,
{
name: 'cool-field-2.field',
type: 'keyword',
subType: {
nested: {
path: 'cool-field-2.field.path',
},
},
},
];
const index = {
...indexPatternMock,
name: 'the-data-view',
timeFieldName: 'cool-timefield',
fields: {
getAll: () => fields,
getByName: (name: string) => fields.find((field) => field.name === name),
},
} as unknown as IndexPattern;
const searchSourceMock = createSearchSourceMock({ index });
const { getSearchSource } = await getSharingData(
searchSourceMock,
{
columns: ['cool-field-1', 'cool-field-2'],
},
services
);
expect(getSearchSource().fields).toStrictEqual([
'cool-timefield',
'cool-field-1',
'cool-field-2.*',
]);
});

test('fields have prepended timeField', async () => {
const index = { ...indexPatternMock } as IndexPattern;
index.timeFieldName = 'cool-timefield';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import type { Capabilities } from 'kibana/public';
import type { IUiSettingsClient } from 'src/core/public';
import type { DataPublicPluginStart } from 'src/plugins/data/public';
import type { Filter, ISearchSource, SearchSourceFields } from 'src/plugins/data/common';
import { escapeRegExp } from 'lodash';
import type { IndexPattern } from 'src/plugins/data/public';
import { getDataViewFieldSubtypeNested } from '@kbn/es-query';
import {
DOC_HIDE_TIME_COLUMN_SETTING,
SORT_DEFAULT_ORDER_SETTING,
Expand Down Expand Up @@ -92,7 +95,20 @@ export async function getSharingData(
*/
const useFieldsApi = !config.get(SEARCH_FIELDS_FROM_SOURCE);
if (useFieldsApi && columns.length) {
searchSource.setField('fields', columns);
searchSource.setField(
'fields',
columns.map((column) => {
let field = column;

// If this column is a nested field, add a wildcard to the field name in order to fetch
// all leaf fields for the report, since the fields API doesn't support nested field roots
if (isNestedFieldParent(column, index)) {
field = `${column}.*`;
}

return field;
})
);
}
return searchSource.getSerializedFields(true);
},
Expand All @@ -115,3 +131,18 @@ export const showPublicUrlSwitch = (anonymousUserCapabilities: Capabilities) =>

return !!discover.show;
};

function isNestedFieldParent(fieldName: string, dataView: IndexPattern): boolean {
const nestedRootRegex = new RegExp(escapeRegExp(fieldName) + '(\\.|$)');
return (
!dataView.fields.getByName(fieldName) &&
!!dataView.fields.getAll().find((patternField) => {
// We only want to match a full path segment
const subTypeNested = getDataViewFieldSubtypeNested(patternField);
if (!subTypeNested) {
return false;
}
return nestedRootRegex.test(subTypeNested?.nested.path ?? '');
})
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,9 @@ describe('GetCsvReportPanelAction', () => {
createCopy: () => mockSearchSource,
removeField: jest.fn(),
setField: jest.fn(),
getField: jest.fn(),
getField: jest.fn((name) =>
name === 'index' ? { fields: { getAll: () => [], getByName: () => undefined } } : undefined
),
getSerializedFields: jest.fn().mockImplementation(() => ({ testData: 'testDataValue' })),
} as unknown as SearchSource;
context.embeddable.getSavedSearch = () => {
Expand Down

0 comments on commit 7a29ee9

Please sign in to comment.