[8.11] [Discover/CSV Reporting] Fix support for nested field columns in CSV reports (#172240) (#172335)

# Backport

This will backport the following commits from `main` to `8.11`:
- [[Discover/CSV Reporting] Fix support for nested field columns in CSV
reports (#172240)](https://github.com/elastic/kibana/pull/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":"davis.mcphee@elastic.co"},"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
<42973632+kibanamachine@users.noreply.github.com>","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
<42973632+kibanamachine@users.noreply.github.com>","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
<42973632+kibanamachine@users.noreply.github.com>","sha":"ab5ff9ca626baa90c3cc0e92813ff70cb5956e23"}}]}]
BACKPORT-->
This commit is contained in:
Davis McPhee 2023-12-01 11:56:34 -04:00 committed by GitHub
parent fb019230f0
commit 11eb765f54
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 3 deletions

View file

@ -16,7 +16,7 @@ import {
SORT_DEFAULT_ORDER_SETTING,
SEARCH_FIELDS_FROM_SOURCE,
} from '@kbn/discover-utils';
import { dataViewMock } from '@kbn/discover-utils/src/__mocks__';
import { buildDataViewMock, dataViewMock } from '@kbn/discover-utils/src/__mocks__';
import { getSharingData, showPublicUrlSwitch } from './get_sharing_data';
describe('getSharingData', () => {
@ -162,6 +162,38 @@ describe('getSharingData', () => {
]);
});
test('getSearchSource supports nested fields', async () => {
const index = buildDataViewMock({
name: 'the-data-view',
timeFieldName: 'cool-timefield',
fields: [
...dataViewMock.fields,
{
name: 'cool-field-2.field',
type: 'keyword',
subType: {
nested: {
path: 'cool-field-2.field.path',
},
},
},
] as DataView['fields'],
});
const searchSourceMock = createSearchSourceMock({ index });
const { getSearchSource } = await getSharingData(
searchSourceMock,
{
columns: ['cool-field-1', 'cool-field-2'],
},
services
);
expect(getSearchSource({}).fields).toStrictEqual([
{ field: 'cool-timefield', include_unmapped: 'true' },
{ field: 'cool-field-1', include_unmapped: 'true' },
{ field: 'cool-field-2.*', include_unmapped: 'true' },
]);
});
test('fields have prepended timeField', async () => {
const index = { ...dataViewMock } as DataView;
index.timeFieldName = 'cool-timefield';

View file

@ -17,6 +17,7 @@ import type { Filter } from '@kbn/es-query';
import type { SavedSearch, SortOrder } from '@kbn/saved-search-plugin/public';
import {
DOC_HIDE_TIME_COLUMN_SETTING,
isNestedFieldParent,
SEARCH_FIELDS_FROM_SOURCE,
SORT_DEFAULT_ORDER_SETTING,
} from '@kbn/discover-utils';
@ -113,7 +114,17 @@ export async function getSharingData(
if (useFieldsApi) {
searchSource.removeField('fieldsFromSource');
const fields = columns.length
? columns.map((field) => ({ field, include_unmapped: 'true' }))
? 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, include_unmapped: 'true' };
})
: [{ field: '*', include_unmapped: 'true' }];
searchSource.setField('fields', fields);

View file

@ -18,6 +18,7 @@ import { ReportingAPIClient } from '../lib/reporting_api_client';
import type { ReportingPublicPluginStartDendencies } from '../plugin';
import type { ActionContext } from './get_csv_panel_action';
import { ReportingCsvPanelAction } from './get_csv_panel_action';
import { dataViewMock } from '@kbn/discover-utils/src/__mocks__';
const core = coreMock.createSetup();
let apiClient: ReportingAPIClient;
@ -124,7 +125,7 @@ describe('GetCsvReportPanelAction', () => {
createCopy: () => mockSearchSource,
removeField: jest.fn(),
setField: jest.fn(),
getField: jest.fn(),
getField: jest.fn((name) => (name === 'index' ? dataViewMock : undefined)),
getSerializedFields: jest.fn().mockImplementation(() => ({ testData: 'testDataValue' })),
} as unknown as SearchSource;
context.embeddable.getSavedSearch = () => {

View file

@ -42,6 +42,7 @@
"@kbn/core-http-router-server-internal",
"@kbn/core-http-common",
"@kbn/react-kibana-context-theme",
"@kbn/discover-utils",
],
"exclude": [
"target/**/*",