diff --git a/x-pack/plugins/ml/public/data_frame/common/request.test.ts b/x-pack/plugins/ml/public/data_frame/common/request.test.ts index 2892e96bcef00..2f16f2494c90a 100644 --- a/x-pack/plugins/ml/public/data_frame/common/request.test.ts +++ b/x-pack/plugins/ml/public/data_frame/common/request.test.ts @@ -11,9 +11,32 @@ import { DefinePivotExposedState } from '../components/define_pivot/define_pivot import { PIVOT_SUPPORTED_GROUP_BY_AGGS } from './pivot_group_by'; import { PivotAggsConfig, PIVOT_SUPPORTED_AGGS } from './pivot_aggs'; -import { getDataFramePreviewRequest, getDataFrameRequest, getPivotQuery } from './request'; +import { + getDataFramePreviewRequest, + getDataFrameRequest, + getPivotQuery, + isDefaultQuery, + isSimpleQuery, + PivotQuery, +} from './request'; + +const defaultQuery: PivotQuery = { query_string: { query: '*' } }; +const matchAllQuery: PivotQuery = { match_all: {} }; +const simpleQuery: PivotQuery = { query_string: { query: 'airline:AAL' } }; describe('Data Frame: Common', () => { + test('isSimpleQuery()', () => { + expect(isSimpleQuery(defaultQuery)).toBe(true); + expect(isSimpleQuery(matchAllQuery)).toBe(false); + expect(isSimpleQuery(simpleQuery)).toBe(true); + }); + + test('isDefaultQuery()', () => { + expect(isDefaultQuery(defaultQuery)).toBe(true); + expect(isDefaultQuery(matchAllQuery)).toBe(false); + expect(isDefaultQuery(simpleQuery)).toBe(false); + }); + test('getPivotQuery()', () => { const query = getPivotQuery('the-query'); diff --git a/x-pack/plugins/ml/public/data_frame/common/request.ts b/x-pack/plugins/ml/public/data_frame/common/request.ts index eb611cd90018f..14aa1cded8ce9 100644 --- a/x-pack/plugins/ml/public/data_frame/common/request.ts +++ b/x-pack/plugins/ml/public/data_frame/common/request.ts @@ -68,6 +68,14 @@ export function getPivotQuery(search: string | SavedSearchQuery): PivotQuery { return search; } +export function isSimpleQuery(arg: any): arg is SimpleQuery { + return arg.query_string !== undefined; +} + +export function isDefaultQuery(query: PivotQuery): boolean { + return isSimpleQuery(query) && query.query_string.query === '*'; +} + export function getDataFramePreviewRequest( indexPatternTitle: IndexPattern['title'], query: PivotQuery, @@ -77,7 +85,6 @@ export function getDataFramePreviewRequest( const request: DataFramePreviewRequest = { source: { index: indexPatternTitle, - query, }, pivot: { group_by: {}, @@ -85,6 +92,10 @@ export function getDataFramePreviewRequest( }, }; + if (!isDefaultQuery(query)) { + request.source.query = query; + } + groupBy.forEach(g => { if (g.agg === PIVOT_SUPPORTED_GROUP_BY_AGGS.TERMS) { const termsAgg: TermsAgg = { diff --git a/x-pack/plugins/ml/public/data_frame/components/define_pivot/common.test.ts b/x-pack/plugins/ml/public/data_frame/components/define_pivot/common.test.ts index 9c591a3d4e705..6431af5bfb5a2 100644 --- a/x-pack/plugins/ml/public/data_frame/components/define_pivot/common.test.ts +++ b/x-pack/plugins/ml/public/data_frame/components/define_pivot/common.test.ts @@ -128,13 +128,7 @@ describe('Data Frame: Define Pivot Common', () => { expect(pivotPreviewDevConsoleStatement).toBe(`POST _data_frame/transforms/_preview { "source": { - "index": "the-index-pattern-title", - "query": { - "query_string": { - "query": "*", - "default_operator": "AND" - } - } + "index": "the-index-pattern-title" }, "pivot": { "group_by": { diff --git a/x-pack/plugins/ml/public/data_frame/components/define_pivot/define_pivot_form.tsx b/x-pack/plugins/ml/public/data_frame/components/define_pivot/define_pivot_form.tsx index 888f662621af8..bf82cc28a4d88 100644 --- a/x-pack/plugins/ml/public/data_frame/components/define_pivot/define_pivot_form.tsx +++ b/x-pack/plugins/ml/public/data_frame/components/define_pivot/define_pivot_form.tsx @@ -191,6 +191,11 @@ export const DefinePivotForm: SFC = React.memo(({ overrides = {}, onChang ] ); + // TODO This should use the actual value of `indices.query.bool.max_clause_count` + const maxIndexFields = 1024; + const numIndexFields = indexPattern.fields.length; + const disabledQuery = numIndexFields > maxIndexFields; + return ( @@ -201,28 +206,42 @@ export const DefinePivotForm: SFC = React.memo(({ overrides = {}, onChang label={i18n.translate('xpack.ml.dataframe.definePivotForm.indexPatternLabel', { defaultMessage: 'Index pattern', })} + helpText={ + disabledQuery + ? i18n.translate('xpack.ml.dataframe.definePivotForm.indexPatternHelpText', { + defaultMessage: + 'An optional query for this index pattern is not supported. The number of supported index fields is {maxIndexFields} whereas this index has {numIndexFields} fields.', + values: { + maxIndexFields, + numIndexFields, + }, + }) + : '' + } > {kibanaContext.currentIndexPattern.title} - - - + {!disabledQuery && ( + + + + )} )} diff --git a/x-pack/plugins/ml/public/data_frame/components/source_index_preview/source_index_preview.tsx b/x-pack/plugins/ml/public/data_frame/components/source_index_preview/source_index_preview.tsx index 542bf4b45ac4c..80477e9f1b684 100644 --- a/x-pack/plugins/ml/public/data_frame/components/source_index_preview/source_index_preview.tsx +++ b/x-pack/plugins/ml/public/data_frame/components/source_index_preview/source_index_preview.tsx @@ -5,6 +5,7 @@ */ import React, { FunctionComponent, useContext, useState } from 'react'; +import moment from 'moment-timezone'; import { i18n } from '@kbn/i18n'; @@ -36,7 +37,9 @@ interface ExpandableTableProps extends EuiInMemoryTableProps { const ExpandableTable = (EuiInMemoryTable as any) as FunctionComponent; +import { KBN_FIELD_TYPES } from '../../../../common/constants/field_types'; import { Dictionary } from '../../../../common/types/common'; +import { formatHumanReadableDateTimeSeconds } from '../../../util/date_utils'; import { isKibanaContext, KibanaContext, PivotQuery } from '../../common'; @@ -208,15 +211,23 @@ export const SourceIndexPreview: React.SFC = React.memo(({ cellClick, que const column = { field: `_source.${k}`, name: k, - render: undefined, sortable: true, truncateText: true, } as Dictionary; + const field = indexPattern.fields.find(f => f.name === k); + const render = (d: string) => { + return field !== undefined && field.type === KBN_FIELD_TYPES.DATE + ? formatHumanReadableDateTimeSeconds(moment(d).unix() * 1000) + : d; + }; + + column.render = render; + if (CELL_CLICK_ENABLED && cellClick) { column.render = (d: string) => ( cellClick(`${k}:(${d})`)}> - {d} + {render(d)} ); } diff --git a/x-pack/plugins/ml/public/data_frame/components/source_index_preview/use_source_index_data.ts b/x-pack/plugins/ml/public/data_frame/components/source_index_preview/use_source_index_data.ts index 433312182dbbf..9183092407596 100644 --- a/x-pack/plugins/ml/public/data_frame/components/source_index_preview/use_source_index_data.ts +++ b/x-pack/plugins/ml/public/data_frame/components/source_index_preview/use_source_index_data.ts @@ -12,7 +12,7 @@ import { IndexPattern } from 'ui/index_patterns'; import { ml } from '../../../services/ml_api_service'; -import { PivotQuery } from '../../common'; +import { isDefaultQuery, PivotQuery } from '../../common'; import { EsDoc, EsFieldName, getDefaultSelectableFields } from './common'; const SEARCH_SIZE = 1000; @@ -48,7 +48,8 @@ export const useSourceIndexData = ( const resp: SearchResponse = await ml.esSearch({ index: indexPattern.title, size: SEARCH_SIZE, - body: { query }, + // Instead of using the default query (`*`), fall back to a more efficient `match_all` query. + body: { query: isDefaultQuery(query) ? { match_all: {} } : query }, }); const docs = resp.hits.hits;