diff --git a/x-pack/plugins/transform/common/types/pivot_group_by.ts b/x-pack/plugins/transform/common/types/pivot_group_by.ts index bfaf17a32b580..3d1a833b1b562 100644 --- a/x-pack/plugins/transform/common/types/pivot_group_by.ts +++ b/x-pack/plugins/transform/common/types/pivot_group_by.ts @@ -12,6 +12,7 @@ export type GenericAgg = object; export interface TermsAgg { terms: { field: EsFieldName; + missing_bucket?: boolean; }; } @@ -19,6 +20,7 @@ export interface HistogramAgg { histogram: { field: EsFieldName; interval: string; + missing_bucket?: boolean; }; } @@ -26,6 +28,7 @@ export interface DateHistogramAgg { date_histogram: { field: EsFieldName; calendar_interval: string; + missing_bucket?: boolean; }; } diff --git a/x-pack/plugins/transform/public/app/common/pivot_group_by.ts b/x-pack/plugins/transform/public/app/common/pivot_group_by.ts index 2c2bac369c72d..281aee0805161 100644 --- a/x-pack/plugins/transform/public/app/common/pivot_group_by.ts +++ b/x-pack/plugins/transform/public/app/common/pivot_group_by.ts @@ -52,17 +52,20 @@ interface GroupByDateHistogram extends GroupByConfigBase { agg: PIVOT_SUPPORTED_GROUP_BY_AGGS.DATE_HISTOGRAM; field: EsFieldName; calendar_interval: string; + missing_bucket?: boolean; } interface GroupByHistogram extends GroupByConfigBase { agg: PIVOT_SUPPORTED_GROUP_BY_AGGS.HISTOGRAM; field: EsFieldName; interval: string; + missing_bucket?: boolean; } interface GroupByTerms extends GroupByConfigBase { agg: PIVOT_SUPPORTED_GROUP_BY_AGGS.TERMS; field: EsFieldName; + missing_bucket?: boolean; } export type GroupByConfigWithInterval = GroupByDateHistogram | GroupByHistogram; diff --git a/x-pack/plugins/transform/public/app/common/request.test.ts b/x-pack/plugins/transform/public/app/common/request.test.ts index 46ace2c3315a5..cc58308a165c8 100644 --- a/x-pack/plugins/transform/public/app/common/request.test.ts +++ b/x-pack/plugins/transform/public/app/common/request.test.ts @@ -18,6 +18,7 @@ import { getPreviewTransformRequestBody, getCreateTransformRequestBody, getCreateTransformSettingsRequestBody, + getMissingBucketConfig, getPivotQuery, isDefaultQuery, isMatchAllQuery, @@ -28,6 +29,20 @@ import { const simpleQuery: PivotQuery = { query_string: { query: 'airline:AAL' } }; +const groupByTerms: PivotGroupByConfig = { + agg: PIVOT_SUPPORTED_GROUP_BY_AGGS.TERMS, + field: 'the-group-by-field', + aggName: 'the-group-by-agg-name', + dropDownName: 'the-group-by-drop-down-name', +}; + +const aggsAvg: PivotAggsConfig = { + agg: PIVOT_SUPPORTED_AGGS.AVG, + field: 'the-agg-field', + aggName: 'the-agg-agg-name', + dropDownName: 'the-agg-drop-down-name', +}; + describe('Transform: Common', () => { test('isMatchAllQuery()', () => { expect(isMatchAllQuery(defaultQuery)).toBe(false); @@ -47,6 +62,16 @@ describe('Transform: Common', () => { expect(isDefaultQuery(simpleQuery)).toBe(false); }); + test('getMissingBucketConfig()', () => { + expect(getMissingBucketConfig(groupByTerms)).toEqual({}); + expect(getMissingBucketConfig({ ...groupByTerms, ...{ missing_bucket: true } })).toEqual({ + missing_bucket: true, + }); + expect(getMissingBucketConfig({ ...groupByTerms, ...{ missing_bucket: false } })).toEqual({ + missing_bucket: false, + }); + }); + test('getPivotQuery()', () => { const query = getPivotQuery('the-query'); @@ -60,22 +85,8 @@ describe('Transform: Common', () => { test('getPreviewTransformRequestBody()', () => { const query = getPivotQuery('the-query'); - const groupBy: PivotGroupByConfig[] = [ - { - agg: PIVOT_SUPPORTED_GROUP_BY_AGGS.TERMS, - field: 'the-group-by-field', - aggName: 'the-group-by-agg-name', - dropDownName: 'the-group-by-drop-down-name', - }, - ]; - const aggs: PivotAggsConfig[] = [ - { - agg: PIVOT_SUPPORTED_AGGS.AVG, - field: 'the-agg-field', - aggName: 'the-agg-agg-name', - dropDownName: 'the-agg-drop-down-name', - }, - ]; + const groupBy: PivotGroupByConfig[] = [groupByTerms]; + const aggs: PivotAggsConfig[] = [aggsAvg]; const request = getPreviewTransformRequestBody('the-index-pattern-title', query, groupBy, aggs); expect(request).toEqual({ @@ -92,22 +103,8 @@ describe('Transform: Common', () => { test('getPreviewTransformRequestBody() with comma-separated index pattern', () => { const query = getPivotQuery('the-query'); - const groupBy: PivotGroupByConfig[] = [ - { - agg: PIVOT_SUPPORTED_GROUP_BY_AGGS.TERMS, - field: 'the-group-by-field', - aggName: 'the-group-by-agg-name', - dropDownName: 'the-group-by-drop-down-name', - }, - ]; - const aggs: PivotAggsConfig[] = [ - { - agg: PIVOT_SUPPORTED_AGGS.AVG, - field: 'the-agg-field', - aggName: 'the-agg-agg-name', - dropDownName: 'the-agg-drop-down-name', - }, - ]; + const groupBy: PivotGroupByConfig[] = [groupByTerms]; + const aggs: PivotAggsConfig[] = [aggsAvg]; const request = getPreviewTransformRequestBody( 'the-index-pattern-title,the-other-title', query, @@ -127,22 +124,30 @@ describe('Transform: Common', () => { }); }); + test('getPreviewTransformRequestBody() with missing_buckets config', () => { + const query = getPivotQuery('the-query'); + const groupBy: PivotGroupByConfig[] = [{ ...groupByTerms, ...{ missing_bucket: true } }]; + const aggs: PivotAggsConfig[] = [aggsAvg]; + const request = getPreviewTransformRequestBody('the-index-pattern-title', query, groupBy, aggs); + + expect(request).toEqual({ + pivot: { + aggregations: { 'the-agg-agg-name': { avg: { field: 'the-agg-field' } } }, + group_by: { + 'the-group-by-agg-name': { terms: { field: 'the-group-by-field', missing_bucket: true } }, + }, + }, + source: { + index: ['the-index-pattern-title'], + query: { query_string: { default_operator: 'AND', query: 'the-query' } }, + }, + }); + }); + test('getCreateTransformRequestBody()', () => { - const groupBy: PivotGroupByConfig = { - agg: PIVOT_SUPPORTED_GROUP_BY_AGGS.TERMS, - field: 'the-group-by-field', - aggName: 'the-group-by-agg-name', - dropDownName: 'the-group-by-drop-down-name', - }; - const agg: PivotAggsConfig = { - agg: PIVOT_SUPPORTED_AGGS.AVG, - field: 'the-agg-field', - aggName: 'the-agg-agg-name', - dropDownName: 'the-agg-drop-down-name', - }; const pivotState: StepDefineExposedState = { - aggList: { 'the-agg-name': agg }, - groupByList: { 'the-group-by-name': groupBy }, + aggList: { 'the-agg-name': aggsAvg }, + groupByList: { 'the-group-by-name': groupByTerms }, isAdvancedPivotEditorEnabled: false, isAdvancedSourceEditorEnabled: false, sourceConfigUpdated: false, diff --git a/x-pack/plugins/transform/public/app/common/request.ts b/x-pack/plugins/transform/public/app/common/request.ts index 8ee235baf7c5a..d92a4ee258757 100644 --- a/x-pack/plugins/transform/public/app/common/request.ts +++ b/x-pack/plugins/transform/public/app/common/request.ts @@ -30,6 +30,7 @@ import { isGroupByDateHistogram, isGroupByHistogram, isGroupByTerms, + GroupByConfigWithUiSupport, PivotGroupByConfig, } from '../common'; @@ -71,6 +72,12 @@ export function isDefaultQuery(query: PivotQuery): boolean { return isSimpleQuery(query) && query.query_string.query === '*'; } +export const getMissingBucketConfig = ( + g: GroupByConfigWithUiSupport +): { missing_bucket?: boolean } => { + return g.missing_bucket !== undefined ? { missing_bucket: g.missing_bucket } : {}; +}; + export function getPreviewTransformRequestBody( indexPatternTitle: IndexPattern['title'], query: PivotQuery, @@ -95,6 +102,7 @@ export function getPreviewTransformRequestBody( const termsAgg: TermsAgg = { terms: { field: g.field, + ...getMissingBucketConfig(g), }, }; request.pivot.group_by[g.aggName] = termsAgg; @@ -103,6 +111,7 @@ export function getPreviewTransformRequestBody( histogram: { field: g.field, interval: g.interval, + ...getMissingBucketConfig(g), }, }; request.pivot.group_by[g.aggName] = histogramAgg; @@ -111,6 +120,7 @@ export function getPreviewTransformRequestBody( date_histogram: { field: g.field, calendar_interval: g.calendar_interval, + ...getMissingBucketConfig(g), }, }; request.pivot.group_by[g.aggName] = dateHistogramAgg;