From faf540d29360d60e3d6e081f9eb3a2c43ee84703 Mon Sep 17 00:00:00 2001 From: neptunian Date: Wed, 22 Jan 2020 08:40:57 -0500 Subject: [PATCH 1/2] handle mult_fields --- .../plugins/epm/server/lib/fields/field.ts | 1 + .../__snapshots__/install.test.ts.snap | 36 +++++++++++++++++++ .../lib/kibana/index_pattern/install.ts | 32 ++++++++++++----- .../index_pattern/tests/nginx.fields.yml | 9 ++++- 4 files changed, 68 insertions(+), 10 deletions(-) diff --git a/x-pack/legacy/plugins/epm/server/lib/fields/field.ts b/x-pack/legacy/plugins/epm/server/lib/fields/field.ts index 8c528e94f30e6a..ddc3c860da63e4 100644 --- a/x-pack/legacy/plugins/epm/server/lib/fields/field.ts +++ b/x-pack/legacy/plugins/epm/server/lib/fields/field.ts @@ -19,6 +19,7 @@ export interface Field { required?: boolean; description?: string; fields?: Fields; + multi_fields?: Fields; searchable?: boolean; aggregatable?: boolean; doc_values?: boolean; diff --git a/x-pack/legacy/plugins/epm/server/lib/kibana/index_pattern/__snapshots__/install.test.ts.snap b/x-pack/legacy/plugins/epm/server/lib/kibana/index_pattern/__snapshots__/install.test.ts.snap index ea62e78044c9aa..1fdea8c07337b1 100644 --- a/x-pack/legacy/plugins/epm/server/lib/kibana/index_pattern/__snapshots__/install.test.ts.snap +++ b/x-pack/legacy/plugins/epm/server/lib/kibana/index_pattern/__snapshots__/install.test.ts.snap @@ -263,6 +263,20 @@ exports[`creating index patterns from yaml fields dedupFields function remove du ] } ] + }, + { + "name": "country", + "type": "", + "multi_fields": [ + { + "name": "keyword", + "type": "keyword" + }, + { + "name": "text", + "type": "text" + } + ] } ] `; @@ -568,6 +582,28 @@ exports[`creating index patterns from yaml fields flattenFields function flatten { "name": "source.geo.continent_name", "type": "text" + }, + { + "name": "country", + "type": "", + "multi_fields": [ + { + "name": "keyword", + "type": "keyword" + }, + { + "name": "text", + "type": "text" + } + ] + }, + { + "name": "country.keyword", + "type": "keyword" + }, + { + "name": "country.text", + "type": "text" } ] `; diff --git a/x-pack/legacy/plugins/epm/server/lib/kibana/index_pattern/install.ts b/x-pack/legacy/plugins/epm/server/lib/kibana/index_pattern/install.ts index 80ddc59fbbb096..0d000f048dd3ac 100644 --- a/x-pack/legacy/plugins/epm/server/lib/kibana/index_pattern/install.ts +++ b/x-pack/legacy/plugins/epm/server/lib/kibana/index_pattern/install.ts @@ -201,16 +201,11 @@ export const transformField = (field: Field, i: number, fields: Fields): IndexPa export const flattenFields = (allFields: Fields): Fields => { const flatten = (fields: Fields): Fields => fields.reduce((acc, field) => { - if (field.fields?.length) { - const flattenedFields = flatten(field.fields); - flattenedFields.forEach(nestedField => { - acc.push({ - ...nestedField, - name: `${field.name}.${nestedField.name}`, - }); - }); + if (field.type === 'group' && field.fields?.length) { + // look for nested fields + acc = renameAndFlatten(field, field.fields, [...acc]); } else { - // handle alias type fields - TODO: this should probably go somewhere else + // handle alias type fields if (field.type === 'alias' && field.path) { const foundField = findFieldByPath(allFields, field.path); // if aliased leaf field is found copy its props over except path and name @@ -219,10 +214,29 @@ export const flattenFields = (allFields: Fields): Fields => { field = { ...foundField, path, name }; } } + // add field before going through multi_fields acc.push(field); + + // for each field in multi_field add new field + if (field.multi_fields?.length) { + acc = renameAndFlatten(field, field.multi_fields, [...acc]); + } } return acc; }, []); + + // helper function to call flatten() and rename the fields + const renameAndFlatten = (field: Field, fields: Fields, acc: Fields): Fields => { + const flattenedFields = flatten(fields); + flattenedFields.forEach(nestedField => { + acc.push({ + ...nestedField, + name: `${field.name}.${nestedField.name}`, + }); + }); + return acc; + }; + return flatten(allFields); }; diff --git a/x-pack/legacy/plugins/epm/server/lib/kibana/index_pattern/tests/nginx.fields.yml b/x-pack/legacy/plugins/epm/server/lib/kibana/index_pattern/tests/nginx.fields.yml index 35035540ac0016..33f51458706a4b 100644 --- a/x-pack/legacy/plugins/epm/server/lib/kibana/index_pattern/tests/nginx.fields.yml +++ b/x-pack/legacy/plugins/epm/server/lib/kibana/index_pattern/tests/nginx.fields.yml @@ -102,4 +102,11 @@ type: group fields: - name: continent_name - type: text \ No newline at end of file + type: text +- name: country + type: "" + multi_fields: + - name: keyword + type: keyword + - name: text + type: text \ No newline at end of file From ff91e5c93b179e9ac03ef0f2986192563faed2de Mon Sep 17 00:00:00 2001 From: neptunian Date: Wed, 22 Jan 2020 08:45:23 -0500 Subject: [PATCH 2/2] move nested function out --- .../lib/kibana/index_pattern/install.ts | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/x-pack/legacy/plugins/epm/server/lib/kibana/index_pattern/install.ts b/x-pack/legacy/plugins/epm/server/lib/kibana/index_pattern/install.ts index 0d000f048dd3ac..c28ca637e8ee72 100644 --- a/x-pack/legacy/plugins/epm/server/lib/kibana/index_pattern/install.ts +++ b/x-pack/legacy/plugins/epm/server/lib/kibana/index_pattern/install.ts @@ -110,29 +110,28 @@ export const dedupeFields = (fields: Fields) => { */ export const findFieldByPath = (allFields: Fields, path: string): Field | undefined => { const pathParts = path.split('.'); - const getField = (fields: Fields, pathNames: string[]): Field | undefined => { - if (!pathNames.length) return undefined; - // get the first rest of path names - const [name, ...restPathNames] = pathNames; - for (const field of fields) { - if (field.name === name) { - // check field's fields, passing in the remaining path names - if (field.fields && field.fields.length > 0) { - return getField(field.fields, restPathNames); - } - // no nested fields to search, but still more names - not found - if (restPathNames.length) { - return undefined; - } - return field; - } - } - return undefined; - }; - return getField(allFields, pathParts); }; +const getField = (fields: Fields, pathNames: string[]): Field | undefined => { + if (!pathNames.length) return undefined; + // get the first rest of path names + const [name, ...restPathNames] = pathNames; + for (const field of fields) { + if (field.name === name) { + // check field's fields, passing in the remaining path names + if (field.fields && field.fields.length > 0) { + return getField(field.fields, restPathNames); + } + // no nested fields to search, but still more names - not found + if (restPathNames.length) { + return undefined; + } + return field; + } + } + return undefined; +}; // check for alias type and copy contents of the aliased field export const transformField = (field: Field, i: number, fields: Fields): IndexPatternField => { const newField: IndexPatternField = {