diff --git a/src/legacy/ui/public/directives/field_name/field_type_name.ts b/src/legacy/ui/public/directives/field_name/field_type_name.ts index 14376b163d6f01..c8c886015cea32 100644 --- a/src/legacy/ui/public/directives/field_name/field_type_name.ts +++ b/src/legacy/ui/public/directives/field_name/field_type_name.ts @@ -61,6 +61,10 @@ export function getFieldTypeName(type: string) { return i18n.translate('common.ui.directives.fieldNameIcons.stringFieldAriaLabel', { defaultMessage: 'String field', }); + case 'nested': + return i18n.translate('common.ui.directives.fieldNameIcons.nestedFieldAriaLabel', { + defaultMessage: 'Nested field', + }); default: return i18n.translate('common.ui.directives.fieldNameIcons.unknownFieldAriaLabel', { defaultMessage: 'Unknown field', diff --git a/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/field_caps_response.test.js b/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/field_caps_response.test.js index 0d787fa56b400a..3ec903d5b18e43 100644 --- a/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/field_caps_response.test.js +++ b/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/field_caps_response.test.js @@ -37,7 +37,7 @@ describe('index_patterns/field_capabilities/field_caps_response', () => { describe('conflicts', () => { it('returns a field for each in response, no filtering', () => { const fields = readFieldCapsResponse(esResponse); - expect(fields).toHaveLength(24); + expect(fields).toHaveLength(25); }); it( @@ -68,8 +68,8 @@ describe('index_patterns/field_capabilities/field_caps_response', () => { sandbox.spy(shouldReadFieldFromDocValuesNS, 'shouldReadFieldFromDocValues'); const fields = readFieldCapsResponse(esResponse); const conflictCount = fields.filter(f => f.type === 'conflict').length; - // +2 is for the object and nested fields which get filtered out of the final return value from readFieldCapsResponse - sinon.assert.callCount(shouldReadFieldFromDocValues, fields.length - conflictCount + 2); + // +1 is for the object field which is filtered out of the final return value from readFieldCapsResponse + sinon.assert.callCount(shouldReadFieldFromDocValues, fields.length - conflictCount + 1); }); it('converts es types to kibana types', () => { @@ -159,10 +159,12 @@ describe('index_patterns/field_capabilities/field_caps_response', () => { }); }); - it('does not include the field actually mapped as nested itself', () => { + it('returns the nested parent as not searchable or aggregatable', () => { const fields = readFieldCapsResponse(esResponse); const child = fields.find(f => f.name === 'nested_object_parent'); - expect(child).toBeUndefined(); + expect(child.type).toBe('nested'); + expect(child.aggregatable).toBe(false); + expect(child.searchable).toBe(false); }); it('should not confuse object children for multi or nested field children', () => { diff --git a/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/field_caps_response.ts b/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/field_caps_response.ts index 2215bd8a95a1d0..0c8c2ce48fa844 100644 --- a/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/field_caps_response.ts +++ b/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/field_caps_response.ts @@ -195,6 +195,6 @@ export function readFieldCapsResponse(fieldCapsResponse: FieldCapsResponse): Fie }); return kibanaFormattedCaps.filter(field => { - return !['object', 'nested'].includes(field.type); + return !['object'].includes(field.type); }); } diff --git a/src/plugins/kibana_react/public/field_icon/field_icon.tsx b/src/plugins/kibana_react/public/field_icon/field_icon.tsx index 0c5d2b0c24831c..7c44fe89d0e7ff 100644 --- a/src/plugins/kibana_react/public/field_icon/field_icon.tsx +++ b/src/plugins/kibana_react/public/field_icon/field_icon.tsx @@ -36,6 +36,7 @@ interface FieldIconProps { | 'number' | '_source' | 'string' + | 'nested' | string; label?: string; size?: IconSize; @@ -61,6 +62,7 @@ export const typeToEuiIconMap: Partial> = { number: { icon: 'number', color: colors[0] }, _source: { icon: 'editorCodeBlock', color: colors[3] }, string: { icon: 'string', color: colors[4] }, + nested: { icon: 'nested', color: colors[2] }, }; /** diff --git a/test/api_integration/apis/index_patterns/fields_for_wildcard_route/response.js b/test/api_integration/apis/index_patterns/fields_for_wildcard_route/response.js index 25a533d39dd81c..555056173ec62f 100644 --- a/test/api_integration/apis/index_patterns/fields_for_wildcard_route/response.js +++ b/test/api_integration/apis/index_patterns/fields_for_wildcard_route/response.js @@ -71,6 +71,14 @@ export default function({ getService }) { name: 'foo', readFromDocValues: true, }, + { + aggregatable: false, + esTypes: ['nested'], + name: 'nestedField', + readFromDocValues: false, + searchable: false, + type: 'nested', + }, { aggregatable: false, esTypes: ['keyword'], @@ -153,6 +161,14 @@ export default function({ getService }) { name: 'foo', readFromDocValues: true, }, + { + aggregatable: false, + esTypes: ['nested'], + name: 'nestedField', + readFromDocValues: false, + searchable: false, + type: 'nested', + }, { aggregatable: false, esTypes: ['keyword'],