From ebc103f61989ad753568808008a2cbcd9629dfe9 Mon Sep 17 00:00:00 2001 From: Melissa Alvarez Date: Tue, 6 Jul 2021 13:43:55 -0400 Subject: [PATCH] [ML] Data Frame Analytics creation: ensure included fields selection table is shown when no docs contain all mapped fields (#104191) * use indexPatternFields if explain error due to missing values in docs * fix types --- .../application/components/data_grid/types.ts | 1 + .../data_frame_analytics/common/analytics.ts | 2 +- .../configuration_step_form.tsx | 40 ++++++++++++++++--- .../components/shared/fetch_explain_data.ts | 9 +++++ .../hooks/use_index_data.ts | 1 + 5 files changed, 47 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/ml/public/application/components/data_grid/types.ts b/x-pack/plugins/ml/public/application/components/data_grid/types.ts index 9dcd6abb432b3..47684ee307e99 100644 --- a/x-pack/plugins/ml/public/application/components/data_grid/types.ts +++ b/x-pack/plugins/ml/public/application/components/data_grid/types.ts @@ -82,6 +82,7 @@ export interface UseIndexDataReturnType | 'resultsField' > { renderCellValue: RenderCellValue; + indexPatternFields?: string[]; } export interface UseDataGridReturnType { diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/common/analytics.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/common/analytics.ts index 669b95cbaeb8c..bac6b0b9274f5 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/common/analytics.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/common/analytics.ts @@ -102,7 +102,7 @@ export enum INDEX_STATUS { export interface FieldSelectionItem { name: string; - mappings_types: string[]; + mappings_types?: string[]; is_included: boolean; is_required: boolean; feature_type?: string; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_form.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_form.tsx index cc01a8c3f9405..47f7c2621802e 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_form.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_form.tsx @@ -115,6 +115,7 @@ export const ConfigurationStepForm: FC = ({ const [fetchingExplainData, setFetchingExplainData] = useState(false); const [maxDistinctValuesError, setMaxDistinctValuesError] = useState(); const [unsupportedFieldsError, setUnsupportedFieldsError] = useState(); + const [noDocsContainMappedFields, setNoDocsContainMappedFields] = useState(false); const [minimumFieldsRequiredMessage, setMinimumFieldsRequiredMessage] = useState< undefined | string >(); @@ -261,9 +262,13 @@ export const ConfigurationStepForm: FC = ({ formToUse.includes = [...includes, dependentVariable]; } - const { success, expectedMemory, fieldSelection, errorMessage } = await fetchExplainData( - formToUse - ); + const { + success, + expectedMemory, + fieldSelection, + errorMessage, + noDocsContainMappedFields: noDocsWithFields, + } = await fetchExplainData(formToUse); if (success) { if (shouldUpdateEstimatedMml) { @@ -286,6 +291,7 @@ export const ConfigurationStepForm: FC = ({ setFieldOptionsFetchFail(false); setMaxDistinctValuesError(undefined); setUnsupportedFieldsError(undefined); + setNoDocsContainMappedFields(false); setIncludesTableItems(fieldSelection ? fieldSelection : []); } @@ -315,6 +321,7 @@ export const ConfigurationStepForm: FC = ({ setFieldOptionsFetchFail(true); setMaxDistinctValuesError(maxDistinctValuesErrorMessage); setUnsupportedFieldsError(unsupportedFieldsErrorMessage); + setNoDocsContainMappedFields(noDocsWithFields); setFetchingExplainData(false); setFormState({ ...(shouldUpdateModelMemoryLimit ? { modelMemoryLimit: fallbackModelMemoryLimit } : {}), @@ -326,6 +333,17 @@ export const ConfigurationStepForm: FC = ({ setFormState({ sourceIndex: currentIndexPattern.title }); }, []); + const indexPatternFieldsTableItems = useMemo(() => { + if (indexData?.indexPatternFields !== undefined) { + return indexData.indexPatternFields.map((field) => ({ + name: field, + is_included: false, + is_required: false, + })); + } + return []; + }, [`${indexData?.indexPatternFields}`]); + useEffect(() => { if (typeof savedSearchQueryStr === 'string') { setFormState({ jobConfigQuery: savedSearchQuery, jobConfigQueryString: savedSearchQueryStr }); @@ -399,7 +417,12 @@ export const ConfigurationStepForm: FC = ({ ? [...updatedIncludes, dependentVariable] : updatedIncludes; - const { success, fieldSelection, errorMessage } = await fetchExplainData(formCopy); + const { + success, + fieldSelection, + errorMessage, + noDocsContainMappedFields: noDocsWithFields, + } = await fetchExplainData(formCopy); if (success) { // update the field selection table const hasRequiredFields = fieldSelection.some( @@ -423,6 +446,7 @@ export const ConfigurationStepForm: FC = ({ setIncludesTableItems(updatedFieldSelection ? updatedFieldSelection : fieldSelection); setMaxDistinctValuesError(undefined); setUnsupportedFieldsError(undefined); + setNoDocsContainMappedFields(noDocsWithFields); setFormState({ includes: updatedIncludes, requiredFieldsError: !hasRequiredFields ? requiredFieldsErrorText : undefined, @@ -444,6 +468,7 @@ export const ConfigurationStepForm: FC = ({ setMaxDistinctValuesError(maxDistinctValuesErrorMessage); setUnsupportedFieldsError(unsupportedFieldsErrorMessage); + setNoDocsContainMappedFields(noDocsWithFields); } } } @@ -501,6 +526,11 @@ export const ConfigurationStepForm: FC = ({ // `undefined` means uninitialized, `null` means initialized but not used. if (savedSearchQuery === undefined) return null; + const tableItems = + includesTableItems.length > 0 && !noDocsContainMappedFields + ? includesTableItems + : indexPatternFieldsTableItems; + return ( @@ -649,7 +679,7 @@ export const ConfigurationStepForm: FC = ({ includes={includes} minimumFieldsRequiredMessage={minimumFieldsRequiredMessage} setMinimumFieldsRequiredMessage={setMinimumFieldsRequiredMessage} - tableItems={includesTableItems} + tableItems={firstUpdate.current ? includesTableItems : tableItems} unsupportedFieldsError={unsupportedFieldsError} setUnsupportedFieldsError={setUnsupportedFieldsError} setFormState={setFormState} diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/shared/fetch_explain_data.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/shared/fetch_explain_data.ts index ec567f1f96156..7c83b0af15107 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/shared/fetch_explain_data.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/shared/fetch_explain_data.ts @@ -27,6 +27,7 @@ export const fetchExplainData = async (formState: State['form']) => { let success = true; let expectedMemory = ''; let fieldSelection: FieldSelectionItem[] = []; + let noDocsContainMappedFields = false; try { delete jobConfig.dest; @@ -45,11 +46,19 @@ export const fetchExplainData = async (formState: State['form']) => { } } + if ( + errorMessage.includes('status_exception') && + errorMessage.includes('Unable to estimate memory usage as no documents') + ) { + noDocsContainMappedFields = true; + } + return { success, expectedMemory, fieldSelection, errorMessage, errorReason, + noDocsContainMappedFields, }; }; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts index ddf88ce79ab5b..b3034d910c7d1 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts @@ -255,6 +255,7 @@ export const useIndexData = ( return { ...dataGrid, + indexPatternFields, renderCellValue, }; };