[ML] Rename index pattern references to data view (Part 2) (#171820)

- Renames references to index patterns to data views in function and
variable names.
- Some inconsistent naming of schemas for data frame analytics was
cleaned up as part of this PR.
- Note this doesn't cover the whole ml owned codebase but just code
related to data frame analytics.
This commit is contained in:
Walter Rafelsberger 2023-11-23 12:42:43 +01:00 committed by GitHub
parent 5d3c1bc2bb
commit aae3e5d087
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
47 changed files with 309 additions and 338 deletions

View file

@ -10,7 +10,7 @@ export {
getDataGridSchemaFromESFieldType,
getDataGridSchemaFromKibanaFieldType,
getFeatureImportance,
getFieldsFromKibanaIndexPattern,
getFieldsFromKibanaDataView,
getNestedOrEscapedVal,
getProcessedFields,
getTopClasses,

View file

@ -83,7 +83,7 @@ export const euiDataGridToolbarSettings = {
* @param {DataView} dataView - The Kibana data view.
* @returns {string[]} - The array of field names from the data view.
*/
export const getFieldsFromKibanaIndexPattern = (dataView: DataView): string[] => {
export const getFieldsFromKibanaDataView = (dataView: DataView): string[] => {
const allFields = dataView.fields.map((f) => f.name);
const dataViewFields: string[] = allFields.filter((f) => {
if (dataView.metaFields.includes(f)) {

View file

@ -158,9 +158,9 @@ export interface UseIndexDataReturnType
*/
renderCellValue: RenderCellValue;
/**
* Optional index pattern fields.
* Optional data view fields.
*/
indexPatternFields?: string[];
dataViewFields?: string[];
/**
* Optional time range.
*/

View file

@ -101,7 +101,7 @@ export interface ScatterplotMatrixProps {
legendType?: LegendType;
searchQuery?: estypes.QueryDslQueryContainer;
runtimeMappings?: RuntimeMappings;
indexPattern?: DataView;
dataView?: DataView;
query?: Query;
}
@ -113,7 +113,7 @@ export const ScatterplotMatrix: FC<ScatterplotMatrixProps> = ({
legendType,
searchQuery,
runtimeMappings,
indexPattern,
dataView,
query,
}) => {
const { esSearch } = useMlApiContext();
@ -210,9 +210,7 @@ export const ScatterplotMatrix: FC<ScatterplotMatrixProps> = ({
vegaSpec.data = {
url: {
'%context%': true,
...(indexPattern?.timeFieldName
? { ['%timefield%']: `${indexPattern?.timeFieldName}` }
: {}),
...(dataView?.timeFieldName ? { ['%timefield%']: `${dataView?.timeFieldName}` } : {}),
index,
body: {
fields: fieldsToFetch,
@ -300,7 +298,7 @@ export const ScatterplotMatrix: FC<ScatterplotMatrixProps> = ({
}
const combinedRuntimeMappings =
indexPattern && getCombinedRuntimeMappings(indexPattern, runtimeMappings);
dataView && getCombinedRuntimeMappings(dataView, runtimeMappings);
const body = {
fields: queryFields,

View file

@ -37,12 +37,10 @@ export const useResultsViewConfig = (jobId: string) => {
} = useMlKibana();
const trainedModelsApiService = useTrainedModelsApiService();
const [indexPattern, setIndexPattern] = useState<DataView | undefined>(undefined);
const [indexPatternErrorMessage, setIndexPatternErrorMessage] = useState<undefined | string>(
undefined
);
const [dataView, setDataView] = useState<DataView | undefined>(undefined);
const [dataViewErrorMessage, setDataViewErrorMessage] = useState<undefined | string>(undefined);
const [isInitialized, setIsInitialized] = useState<boolean>(false);
const [needsDestIndexPattern, setNeedsDestIndexPattern] = useState<boolean>(false);
const [needsDestDataView, setNeedsDestDataView] = useState<boolean>(false);
const [isLoadingJobConfig, setIsLoadingJobConfig] = useState<boolean>(false);
const [jobConfig, setJobConfig] = useState<DataFrameAnalyticsConfig | undefined>(undefined);
const [jobCapsServiceErrorMessage, setJobCapsServiceErrorMessage] = useState<undefined | string>(
@ -100,39 +98,39 @@ export const useResultsViewConfig = (jobId: string) => {
try {
const destIndex = getDestinationIndex(jobConfigUpdate);
const destDataViewId = (await getDataViewIdFromName(destIndex)) ?? destIndex;
let dataView: DataView | undefined;
let fetchedDataView: DataView | undefined;
try {
dataView = await dataViews.get(destDataViewId);
fetchedDataView = await dataViews.get(destDataViewId);
// Force refreshing the fields list here because a user directly coming
// from the job creation wizard might land on the page without the
// data view being fully initialized because it was created
// before the analytics job populated the destination index.
await dataViews.refreshFields(dataView);
await dataViews.refreshFields(fetchedDataView);
} catch (e) {
dataView = undefined;
fetchedDataView = undefined;
}
if (dataView === undefined) {
setNeedsDestIndexPattern(true);
if (fetchedDataView === undefined) {
setNeedsDestDataView(true);
const sourceIndex = jobConfigUpdate.source.index[0];
const sourceDataViewId = (await getDataViewIdFromName(sourceIndex)) ?? sourceIndex;
try {
dataView = await dataViews.get(sourceDataViewId);
fetchedDataView = await dataViews.get(sourceDataViewId);
} catch (e) {
dataView = undefined;
fetchedDataView = undefined;
}
}
if (dataView !== undefined) {
await newJobCapsServiceAnalytics.initializeFromDataVIew(dataView);
if (fetchedDataView !== undefined) {
await newJobCapsServiceAnalytics.initializeFromDataVIew(fetchedDataView);
setJobConfig(analyticsConfigs.data_frame_analytics[0]);
setIndexPattern(dataView);
setDataView(fetchedDataView);
setIsInitialized(true);
setIsLoadingJobConfig(false);
} else {
setIndexPatternErrorMessage(
setDataViewErrorMessage(
i18n.translate('xpack.ml.dataframe.analytics.results.dataViewMissingErrorMessage', {
defaultMessage:
'To view this page, a Kibana data view is necessary for either the destination or source index of this analytics job.',
@ -153,15 +151,15 @@ export const useResultsViewConfig = (jobId: string) => {
}, []);
return {
indexPattern,
indexPatternErrorMessage,
dataView,
dataViewErrorMessage,
isInitialized,
isLoadingJobConfig,
jobCapsServiceErrorMessage,
jobConfig,
jobConfigErrorMessage,
jobStatus,
needsDestIndexPattern,
needsDestDataView,
totalFeatureImportance,
};
};

View file

@ -356,9 +356,9 @@ export const ConfigurationStepForm: FC<ConfigurationStepProps> = ({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const indexPatternFieldsTableItems = useMemo(() => {
if (indexData?.indexPatternFields !== undefined) {
return indexData.indexPatternFields.map((field) => ({
const dataViewFieldsTableItems = useMemo(() => {
if (indexData?.dataViewFields !== undefined) {
return indexData.dataViewFields.map((field) => ({
name: field,
is_included: false,
is_required: false,
@ -366,7 +366,7 @@ export const ConfigurationStepForm: FC<ConfigurationStepProps> = ({
}
return [];
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [`${indexData?.indexPatternFields}`]);
}, [`${indexData?.dataViewFields}`]);
useEffect(() => {
if (typeof savedSearchQueryStr === 'string') {
@ -377,11 +377,11 @@ export const ConfigurationStepForm: FC<ConfigurationStepProps> = ({
useEffect(() => {
if (isJobTypeWithDepVar) {
const indexPatternRuntimeFields = getCombinedRuntimeMappings(selectedDataView);
const dataViewRuntimeFields = getCombinedRuntimeMappings(selectedDataView);
let runtimeOptions;
if (indexPatternRuntimeFields) {
runtimeOptions = getRuntimeDepVarOptions(jobType, indexPatternRuntimeFields);
if (dataViewRuntimeFields) {
runtimeOptions = getRuntimeDepVarOptions(jobType, dataViewRuntimeFields);
}
loadDepVarOptions(form, runtimeOptions);
@ -527,7 +527,7 @@ export const ConfigurationStepForm: FC<ConfigurationStepProps> = ({
legendType: getScatterplotMatrixLegendType(jobType),
searchQuery: jobConfigQuery,
runtimeMappings,
indexPattern: selectedDataView,
dataView: selectedDataView,
}),
// eslint-disable-next-line react-hooks/exhaustive-deps
[
@ -571,7 +571,7 @@ export const ConfigurationStepForm: FC<ConfigurationStepProps> = ({
const tableItems =
includesTableItems.length > 0 && !noDocsContainMappedFields
? includesTableItems
: indexPatternFieldsTableItems;
: dataViewFieldsTableItems;
return (
<FieldStatsFlyoutProvider
@ -592,7 +592,7 @@ export const ConfigurationStepForm: FC<ConfigurationStepProps> = ({
fullWidth
>
<ExplorationQueryBar
indexPattern={selectedDataView}
dataView={selectedDataView}
setSearchQuery={setJobConfigQuery}
query={query}
/>

View file

@ -42,13 +42,8 @@ export const CreateStep: FC<Props> = ({ actions, state, step }) => {
const { createAnalyticsJob, setFormState, startAnalyticsJob } = actions;
const { isAdvancedEditorValidJson, isJobCreated, isJobStarted, isValid, requestMessages } = state;
const {
createIndexPattern,
destinationIndex,
destinationIndexPatternTitleExists,
jobId,
jobType,
} = state.form;
const { createDataView, destinationIndex, destinationDataViewTitleExists, jobId, jobType } =
state.form;
const [startChecked, setStartChecked] = useState<boolean>(true);
const [creationTriggered, setCreationTriggered] = useState<boolean>(false);
@ -56,7 +51,7 @@ export const CreateStep: FC<Props> = ({ actions, state, step }) => {
useEffect(() => {
if (canCreateDataView === false) {
setFormState({ createIndexPattern: false });
setFormState({ createDataView: false });
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [capabilities]);
@ -106,7 +101,7 @@ export const CreateStep: FC<Props> = ({ actions, state, step }) => {
onChange={(e) => {
setStartChecked(e.target.checked);
if (e.target.checked === false) {
setFormState({ createIndexPattern: false });
setFormState({ createDataView: false });
}
}}
/>
@ -117,8 +112,8 @@ export const CreateStep: FC<Props> = ({ actions, state, step }) => {
<EuiFormRow
fullWidth
isInvalid={
(createIndexPattern && destinationIndexPatternTitleExists) ||
createIndexPattern === false ||
(createDataView && destinationDataViewTitleExists) ||
createDataView === false ||
canCreateDataView === false
}
error={[
@ -134,7 +129,7 @@ export const CreateStep: FC<Props> = ({ actions, state, step }) => {
</EuiText>,
]
: []),
...(createIndexPattern && destinationIndexPatternTitleExists
...(createDataView && destinationDataViewTitleExists
? [
i18n.translate(
'xpack.ml.dataframe.analytics.create.dataViewExistsError',
@ -146,7 +141,7 @@ export const CreateStep: FC<Props> = ({ actions, state, step }) => {
),
]
: []),
...(!createIndexPattern && !destinationIndexPatternTitleExists
...(!createDataView && !destinationDataViewTitleExists
? [
<EuiText size="xs" color="warning">
{i18n.translate(
@ -171,8 +166,8 @@ export const CreateStep: FC<Props> = ({ actions, state, step }) => {
defaultMessage: 'Create data view',
}
)}
checked={createIndexPattern === true}
onChange={() => setFormState({ createIndexPattern: !createIndexPattern })}
checked={createDataView === true}
onChange={() => setFormState({ createDataView: !createDataView })}
data-test-subj="mlAnalyticsCreateJobWizardCreateDataViewCheckbox"
/>
</EuiFormRow>
@ -186,7 +181,7 @@ export const CreateStep: FC<Props> = ({ actions, state, step }) => {
disabled={
!isValid ||
!isAdvancedEditorValidJson ||
(destinationIndexPatternTitleExists === true && createIndexPattern === true)
(destinationDataViewTitleExists === true && createDataView === true)
}
onClick={handleCreation}
fill

View file

@ -25,7 +25,7 @@ import {
getFieldType,
getDataGridSchemaFromKibanaFieldType,
getDataGridSchemaFromESFieldType,
getFieldsFromKibanaIndexPattern,
getFieldsFromKibanaDataView,
showDataGridColumnChartErrorMessageToast,
useDataGrid,
useRenderCellValue,
@ -58,8 +58,8 @@ function getRuntimeFieldColumns(runtimeMappings: RuntimeMappings) {
});
}
function getIndexPatternColumns(indexPattern: DataView, fieldsFilter: string[]) {
const { fields } = indexPattern;
function getDataViewColumns(dataView: DataView, fieldsFilter: string[]) {
const { fields } = dataView;
return fields
.filter((field) => fieldsFilter.includes(field.name))
@ -78,7 +78,7 @@ function getIndexPatternColumns(indexPattern: DataView, fieldsFilter: string[])
}
export const useIndexData = (
indexPattern: DataView,
dataView: DataView,
query: Record<string, any> | undefined,
toastNotifications: CoreSetup['notifications']['toasts'],
runtimeMappings?: RuntimeMappings
@ -87,7 +87,7 @@ export const useIndexData = (
// This is a workaround to avoid passing potentially thousands of unpopulated fields
// (for example, as part of filebeat/metricbeat/ECS based indices)
// to the data grid component which would significantly slow down the page.
const [indexPatternFields, setIndexPatternFields] = useState<string[]>();
const [dataViewFields, setDataViewFields] = useState<string[]>();
const [timeRangeMs, setTimeRangeMs] = useState<TimeRangeMs | undefined>();
useEffect(() => {
@ -96,7 +96,7 @@ export const useIndexData = (
setStatus(INDEX_STATUS.LOADING);
const esSearchRequest = {
index: indexPattern.title,
index: dataView.title,
body: {
fields: ['*'],
_source: false,
@ -116,13 +116,13 @@ export const useIndexData = (
// Get all field names for each returned doc and flatten it
// to a list of unique field names used across all docs.
const allDataViewFields = getFieldsFromKibanaIndexPattern(indexPattern);
const allDataViewFields = getFieldsFromKibanaDataView(dataView);
const populatedFields = [...new Set(docs.map(Object.keys).flat(1))]
.filter((d) => allDataViewFields.includes(d))
.sort();
setStatus(INDEX_STATUS.LOADED);
setIndexPatternFields(populatedFields);
setDataViewFields(populatedFields);
} catch (e) {
setErrorMessage(extractErrorMessage(e));
setStatus(INDEX_STATUS.ERROR);
@ -136,20 +136,20 @@ export const useIndexData = (
// To be used for data grid column selection
// and will be applied to doc and chart queries.
const combinedRuntimeMappings = useMemo(
() => getCombinedRuntimeMappings(indexPattern, runtimeMappings),
[indexPattern, runtimeMappings]
() => getCombinedRuntimeMappings(dataView, runtimeMappings),
[dataView, runtimeMappings]
);
// Available data grid columns, will be a combination of index pattern and runtime fields.
const [columns, setColumns] = useState<MLEuiDataGridColumn[]>([]);
useEffect(() => {
if (Array.isArray(indexPatternFields)) {
if (Array.isArray(dataViewFields)) {
setColumns([
...getIndexPatternColumns(indexPattern, indexPatternFields),
...getDataViewColumns(dataView, dataViewFields),
...(combinedRuntimeMappings ? getRuntimeFieldColumns(combinedRuntimeMappings) : []),
]);
}
}, [indexPattern, indexPatternFields, combinedRuntimeMappings]);
}, [dataView, dataViewFields, combinedRuntimeMappings]);
const dataGrid = useDataGrid(columns);
@ -175,19 +175,19 @@ export const useIndexData = (
setErrorMessage('');
setStatus(INDEX_STATUS.LOADING);
const timeFieldName = indexPattern.getTimeField()?.name;
const timeFieldName = dataView.getTimeField()?.name;
const sort: EsSorting = sortingColumns.reduce((s, column) => {
s[column.id] = { order: column.direction };
return s;
}, {} as EsSorting);
const esSearchRequest = {
index: indexPattern.title,
index: dataView.title,
body: {
query,
from: pagination.pageIndex * pagination.pageSize,
size: pagination.pageSize,
fields: [
...(indexPatternFields ?? []),
...(dataViewFields ?? []),
...(isRuntimeMappings(combinedRuntimeMappings)
? Object.keys(combinedRuntimeMappings)
: []),
@ -246,22 +246,22 @@ export const useIndexData = (
}
}
if (indexPatternFields !== undefined && query !== undefined) {
if (dataViewFields !== undefined && query !== undefined) {
fetchIndexData();
}
// custom comparison
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
indexPattern.title,
indexPatternFields,
dataView.title,
dataViewFields,
// eslint-disable-next-line react-hooks/exhaustive-deps
JSON.stringify([query, pagination, sortingColumns, combinedRuntimeMappings]),
]);
const dataLoader = useMemo(
() => new DataLoader(indexPattern, toastNotifications),
() => new DataLoader(dataView, toastNotifications),
// eslint-disable-next-line react-hooks/exhaustive-deps
[indexPattern]
[dataView]
);
useEffect(() => {
@ -291,16 +291,16 @@ export const useIndexData = (
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
dataGrid.chartsVisible,
indexPattern.title,
dataView.title,
// eslint-disable-next-line react-hooks/exhaustive-deps
JSON.stringify([query, dataGrid.visibleColumns, runtimeMappings]),
]);
const renderCellValue = useRenderCellValue(indexPattern, pagination, tableItems);
const renderCellValue = useRenderCellValue(dataView, pagination, tableItems);
return {
...dataGrid,
indexPatternFields,
dataViewFields,
renderCellValue,
timeRangeMs,
};

View file

@ -15,7 +15,7 @@ interface Props {
destIndex?: string;
}
export const IndexPatternPrompt: FC<Props> = ({ destIndex, color }) => {
export const DataViewPrompt: FC<Props> = ({ destIndex, color }) => {
const {
services: {
http: { basePath },

View file

@ -59,7 +59,7 @@ import { replaceStringTokens } from '../../../../../util/string_utils';
import { parseInterval } from '../../../../../../../common/util/parse_interval';
import { ExpandableSection, ExpandableSectionProps, HEADER_ITEMS_LOADING } from '.';
import { IndexPatternPrompt } from '../index_pattern_prompt';
import { DataViewPrompt } from '../data_view_prompt';
const showingDocs = i18n.translate(
'xpack.ml.dataframe.analytics.explorationResults.documentsShownHelpText',
@ -121,9 +121,9 @@ const getResultsSectionHeaderItems = (
interface ExpandableSectionResultsProps {
colorRange?: ReturnType<typeof useColorRange>;
indexData: UseIndexDataReturnType;
indexPattern?: DataView;
dataView?: DataView;
jobConfig?: DataFrameAnalyticsConfig;
needsDestIndexPattern: boolean;
needsDestDataView: boolean;
resultsField?: string;
searchQuery: estypes.QueryDslQueryContainer;
}
@ -131,9 +131,9 @@ interface ExpandableSectionResultsProps {
export const ExpandableSectionResults: FC<ExpandableSectionResultsProps> = ({
colorRange,
indexData,
indexPattern,
dataView,
jobConfig,
needsDestIndexPattern,
needsDestDataView,
resultsField,
searchQuery,
}) => {
@ -146,7 +146,7 @@ export const ExpandableSectionResults: FC<ExpandableSectionResultsProps> = ({
},
} = useMlKibana();
const dataViewId = indexPattern?.id;
const dataViewId = dataView?.id;
const discoverLocator = useMemo(
() => share.url.locators.get('DISCOVER_APP_LOCATOR'),
@ -206,7 +206,7 @@ export const ExpandableSectionResults: FC<ExpandableSectionResultsProps> = ({
if (discoverLocator !== undefined) {
const url = await discoverLocator.getRedirectUrl({
indexPatternId: dataViewId,
dataViewId,
timeRange: data.query.timefilter.timefilter.getTime(),
filters: data.query.filterManager.getFilters(),
query: {
@ -239,7 +239,7 @@ export const ExpandableSectionResults: FC<ExpandableSectionResultsProps> = ({
if (timeRangeInterval !== null) {
// Create a copy of the record as we are adding properties into it.
const record = cloneDeep(item);
const timestamp = record[indexPattern!.timeFieldName!];
const timestamp = record[dataView!.timeFieldName!];
const configuredUrlValue = customUrl.url_value;
if (configuredUrlValue.includes('$earliest$')) {
@ -373,9 +373,9 @@ export const ExpandableSectionResults: FC<ExpandableSectionResultsProps> = ({
const resultsSectionContent = (
<>
{jobConfig !== undefined && needsDestIndexPattern && (
{jobConfig !== undefined && needsDestDataView && (
<div className="mlExpandableSection-contentPadding">
<IndexPatternPrompt destIndex={jobConfig.dest.index} />
<DataViewPrompt destIndex={jobConfig.dest.index} />
</div>
)}
{jobConfig !== undefined &&
@ -386,7 +386,7 @@ export const ExpandableSectionResults: FC<ExpandableSectionResultsProps> = ({
</EuiText>
)}
{(columnsWithCharts.length > 0 || searchQuery !== defaultSearchQuery) &&
indexPattern !== undefined && (
dataView !== undefined && (
<>
{columnsWithCharts.length > 0 &&
(tableItems.length > 0 || status === INDEX_STATUS.LOADED) && (

View file

@ -35,7 +35,7 @@ import { LoadingPanel } from '../loading_panel';
import { FeatureImportanceSummaryPanelProps } from '../total_feature_importance_summary/feature_importance_summary';
import { useExplorationUrlState } from '../../hooks/use_exploration_url_state';
import { ExplorationQueryBarProps } from '../exploration_query_bar/exploration_query_bar';
import { IndexPatternPrompt } from '../index_pattern_prompt';
import { DataViewPrompt } from '../data_view_prompt';
function getFilters(resultsField: string) {
return {
@ -84,15 +84,15 @@ export const ExplorationPageWrapper: FC<Props> = ({
FeatureImportanceSummaryPanel,
}) => {
const {
indexPattern,
indexPatternErrorMessage,
dataView,
dataViewErrorMessage,
isInitialized,
isLoadingJobConfig,
jobCapsServiceErrorMessage,
jobConfig,
jobConfigErrorMessage,
jobStatus,
needsDestIndexPattern,
needsDestDataView,
totalFeatureImportance,
} = useResultsViewConfig(jobId);
@ -121,13 +121,13 @@ export const ExplorationPageWrapper: FC<Props> = ({
const destIndex = getDestinationIndex(jobConfig);
const scatterplotFieldOptions = useScatterplotFieldOptions(
indexPattern,
dataView,
jobConfig?.analyzed_fields?.includes,
jobConfig?.analyzed_fields?.excludes,
resultsField
);
if (indexPatternErrorMessage !== undefined) {
if (dataViewErrorMessage !== undefined) {
return (
<EuiPanel grow={false}>
<EuiCallOut
@ -138,10 +138,8 @@ export const ExplorationPageWrapper: FC<Props> = ({
iconType="cross"
>
<p>
{indexPatternErrorMessage}
{needsDestIndexPattern ? (
<IndexPatternPrompt destIndex={destIndex} color="text" />
) : null}
{dataViewErrorMessage}
{needsDestDataView ? <DataViewPrompt destIndex={destIndex} color="text" /> : null}
</p>
</EuiCallOut>
</EuiPanel>
@ -170,7 +168,7 @@ export const ExplorationPageWrapper: FC<Props> = ({
</>
)}
{indexPattern !== undefined && jobConfig && (
{dataView !== undefined && jobConfig && (
<>
<EuiFlexGroup direction="column">
<EuiFlexItem grow={false}>
@ -178,7 +176,7 @@ export const ExplorationPageWrapper: FC<Props> = ({
<EuiFlexGroup justifyContent="spaceBetween">
<EuiFlexItem>
<ExplorationQueryBar
indexPattern={indexPattern}
dataView={dataView}
setSearchQuery={searchQueryUpdateHandler}
query={query}
filters={getFilters(jobConfig.dest.results_field!)}
@ -227,7 +225,7 @@ export const ExplorationPageWrapper: FC<Props> = ({
<ExpandableSectionSplom
fields={scatterplotFieldOptions}
index={jobConfig?.dest.index}
indexPattern={indexPattern}
dataView={dataView}
color={
jobType === ANALYSIS_CONFIG_TYPE.REGRESSION ||
jobType === ANALYSIS_CONFIG_TYPE.CLASSIFICATION
@ -242,13 +240,13 @@ export const ExplorationPageWrapper: FC<Props> = ({
{isLoadingJobConfig === true && jobConfig === undefined && <LoadingPanel />}
{isLoadingJobConfig === false &&
jobConfig !== undefined &&
indexPattern !== undefined &&
dataView !== undefined &&
isInitialized === true && (
<ExplorationResultsTable
indexPattern={indexPattern}
dataView={dataView}
jobConfig={jobConfig}
jobStatus={jobStatus}
needsDestIndexPattern={needsDestIndexPattern}
needsDestDataView={needsDestDataView}
searchQuery={searchQuery}
/>
)}

View file

@ -25,7 +25,7 @@ import { removeFilterFromQueryString } from '../../../../../explorer/explorer_ut
import { useMlKibana } from '../../../../../contexts/kibana';
export interface ExplorationQueryBarProps {
indexPattern: DataView;
dataView: DataView;
setSearchQuery: (update: {
queryString: string;
query?: estypes.QueryDslQueryContainer;
@ -41,7 +41,7 @@ export interface ExplorationQueryBarProps {
}
export const ExplorationQueryBar: FC<ExplorationQueryBarProps> = ({
indexPattern,
dataView,
setSearchQuery,
filters,
query,
@ -99,7 +99,7 @@ export const ExplorationQueryBar: FC<ExplorationQueryBarProps> = ({
case SEARCH_QUERY_LANGUAGE.KUERY:
convertedQuery = toElasticsearchQuery(
fromKueryExpression(query.query as string),
indexPattern
dataView
);
break;
case SEARCH_QUERY_LANGUAGE.LUCENE:
@ -181,7 +181,7 @@ export const ExplorationQueryBar: FC<ExplorationQueryBarProps> = ({
<QueryStringInput
bubbleSubmitEvent={false}
query={searchInput}
indexPatterns={[indexPattern]}
indexPatterns={[dataView]}
onChange={searchChangeHandler}
onSubmit={searchSubmitHandler}
placeholder={

View file

@ -23,15 +23,15 @@ import { ExpandableSectionResults } from '../expandable_section';
import { useExplorationResults } from './use_exploration_results';
interface Props {
indexPattern: DataView;
dataView: DataView;
jobConfig: DataFrameAnalyticsConfig;
jobStatus?: DataFrameTaskStateType;
needsDestIndexPattern: boolean;
needsDestDataView: boolean;
searchQuery: ResultsSearchQuery;
}
export const ExplorationResultsTable: FC<Props> = React.memo(
({ indexPattern, jobConfig, needsDestIndexPattern, searchQuery }) => {
({ dataView, jobConfig, needsDestDataView, searchQuery }) => {
const {
services: {
mlServices: { mlApiServices },
@ -39,7 +39,7 @@ export const ExplorationResultsTable: FC<Props> = React.memo(
} = useMlKibana();
const classificationData = useExplorationResults(
indexPattern,
dataView,
jobConfig,
searchQuery,
getToastNotifications(),
@ -54,10 +54,10 @@ export const ExplorationResultsTable: FC<Props> = React.memo(
<div data-test-subj="mlDFAnalyticsExplorationTablePanel">
<ExpandableSectionResults
indexData={classificationData}
indexPattern={indexPattern}
dataView={dataView}
resultsField={jobConfig?.dest.results_field}
jobConfig={jobConfig}
needsDestIndexPattern={needsDestIndexPattern}
needsDestDataView={needsDestDataView}
searchQuery={searchQuery}
/>
</div>

View file

@ -43,7 +43,7 @@ import { useTrainedModelsApiService } from '../../../../../services/ml_api_servi
import { useExplorationDataGrid } from './use_exploration_data_grid';
export const useExplorationResults = (
indexPattern: DataView | undefined,
dataView: DataView | undefined,
jobConfig: DataFrameAnalyticsConfig | undefined,
searchQuery: estypes.QueryDslQueryContainer,
toastNotifications: CoreSetup['notifications']['toasts'],
@ -54,7 +54,7 @@ export const useExplorationResults = (
const trainedModelsApiService = useTrainedModelsApiService();
const needsDestIndexFields =
indexPattern !== undefined && indexPattern.title === jobConfig?.source.index[0];
dataView !== undefined && dataView.title === jobConfig?.source.index[0];
const columns: EuiDataGridColumn[] = [];
@ -90,10 +90,9 @@ export const useExplorationResults = (
}, [jobConfig && jobConfig.id, dataGrid.pagination, searchQuery, dataGrid.sortingColumns]);
const dataLoader = useMemo(
() =>
indexPattern !== undefined ? new DataLoader(indexPattern, toastNotifications) : undefined,
() => (dataView !== undefined ? new DataLoader(dataView, toastNotifications) : undefined),
// eslint-disable-next-line react-hooks/exhaustive-deps
[indexPattern]
[dataView]
);
const fetchColumnChartsData = async function () {
@ -179,7 +178,7 @@ export const useExplorationResults = (
const resultsField = jobConfig?.dest.results_field ?? DEFAULT_RESULTS_FIELD;
const renderCellValue = useRenderCellValue(
indexPattern,
dataView,
dataGrid.pagination,
dataGrid.tableItems,
resultsField

View file

@ -37,7 +37,7 @@ export const JobConfigErrorCallout: FC<Props> = ({
application: { getUrlForApp },
},
} = useMlKibana();
const containsIndexPatternLink =
const containsDataViewLink =
typeof jobCapsServiceErrorMessage === 'string' &&
jobCapsServiceErrorMessage.includes('locate that index-pattern') &&
jobCapsServiceErrorMessage.includes('click here to re-create');
@ -45,7 +45,7 @@ export const JobConfigErrorCallout: FC<Props> = ({
const message = (
<p>{jobConfigErrorMessage ? jobConfigErrorMessage : jobCapsServiceErrorMessage}</p>
);
const newIndexPatternUrl = useMemo(
const newDataViewUrl = useMemo(
() =>
getUrlForApp('management', {
path: 'kibana/indexPatterns',
@ -54,8 +54,8 @@ export const JobConfigErrorCallout: FC<Props> = ({
[]
);
const calloutBody = containsIndexPatternLink ? (
<EuiLink href={newIndexPatternUrl} target="_blank">
const calloutBody = containsDataViewLink ? (
<EuiLink href={newDataViewUrl} target="_blank">
{message}
</EuiLink>
) : (

View file

@ -33,7 +33,7 @@ import { getFeatureCount } from './common';
import { useOutlierData } from './use_outlier_data';
import { useExplorationUrlState } from '../../hooks/use_exploration_url_state';
import { ExplorationQueryBarProps } from '../exploration_query_bar/exploration_query_bar';
import { IndexPatternPrompt } from '../index_pattern_prompt';
import { DataViewPrompt } from '../data_view_prompt';
export type TableItem = Record<string, any>;
@ -42,12 +42,12 @@ interface ExplorationProps {
}
export const OutlierExploration: FC<ExplorationProps> = React.memo(({ jobId }) => {
const { indexPattern, indexPatternErrorMessage, jobConfig, needsDestIndexPattern } =
const { dataView, dataViewErrorMessage, jobConfig, needsDestDataView } =
useResultsViewConfig(jobId);
const [pageUrlState, setPageUrlState] = useExplorationUrlState();
const [searchQuery, setSearchQuery] =
useState<estypes.QueryDslQueryContainer>(defaultSearchQuery);
const outlierData = useOutlierData(indexPattern, jobConfig, searchQuery);
const outlierData = useOutlierData(dataView, jobConfig, searchQuery);
const searchQueryUpdateHandler: ExplorationQueryBarProps['setSearchQuery'] = useCallback(
(update) => {
@ -81,20 +81,20 @@ export const OutlierExploration: FC<ExplorationProps> = React.memo(({ jobId }) =
// If feature influence was enabled for the legacy job we'll show a callout
// with some additional information for a workaround.
const showLegacyFeatureInfluenceFormatCallout =
!needsDestIndexPattern &&
!needsDestDataView &&
isOutlierAnalysis(jobConfig?.analysis) &&
jobConfig?.analysis.outlier_detection.compute_feature_influence === true &&
columnsWithCharts.findIndex((d) => d.id === `${resultsField}.${FEATURE_INFLUENCE}`) === -1;
const scatterplotFieldOptions = useScatterplotFieldOptions(
indexPattern,
dataView,
jobConfig?.analyzed_fields?.includes,
jobConfig?.analyzed_fields?.excludes,
resultsField
);
const destIndex = getDestinationIndex(jobConfig);
if (indexPatternErrorMessage !== undefined) {
if (dataViewErrorMessage !== undefined) {
return (
<EuiPanel grow={false} hasShadow={false} hasBorder>
<EuiCallOut
@ -105,10 +105,8 @@ export const OutlierExploration: FC<ExplorationProps> = React.memo(({ jobId }) =
iconType="cross"
>
<p>
{indexPatternErrorMessage}
{needsDestIndexPattern ? (
<IndexPatternPrompt destIndex={destIndex} color="text" />
) : null}
{dataViewErrorMessage}
{needsDestDataView ? <DataViewPrompt destIndex={destIndex} color="text" /> : null}
</p>
</EuiCallOut>
</EuiPanel>
@ -124,10 +122,10 @@ export const OutlierExploration: FC<ExplorationProps> = React.memo(({ jobId }) =
</>
)}
{(columnsWithCharts.length > 0 || searchQuery !== defaultSearchQuery) &&
indexPattern !== undefined && (
dataView !== undefined && (
<>
<ExplorationQueryBar
indexPattern={indexPattern}
dataView={dataView}
setSearchQuery={searchQueryUpdateHandler}
query={query}
/>
@ -165,9 +163,9 @@ export const OutlierExploration: FC<ExplorationProps> = React.memo(({ jobId }) =
showColorRange && !showLegacyFeatureInfluenceFormatCallout ? colorRange : undefined
}
indexData={outlierData}
indexPattern={indexPattern}
dataView={dataView}
jobConfig={jobConfig}
needsDestIndexPattern={needsDestIndexPattern}
needsDestDataView={needsDestDataView}
searchQuery={searchQuery}
/>
</>

View file

@ -41,17 +41,17 @@ import { getFeatureCount, getOutlierScoreFieldName } from './common';
import { useExplorationDataGrid } from '../exploration_results_table/use_exploration_data_grid';
export const useOutlierData = (
indexPattern: DataView | undefined,
dataView: DataView | undefined,
jobConfig: DataFrameAnalyticsConfig | undefined,
searchQuery: estypes.QueryDslQueryContainer
): UseIndexDataReturnType => {
const needsDestIndexFields =
indexPattern !== undefined && indexPattern.title === jobConfig?.source.index[0];
dataView !== undefined && dataView.title === jobConfig?.source.index[0];
const columns = useMemo(() => {
const newColumns: EuiDataGridColumn[] = [];
if (jobConfig !== undefined && indexPattern !== undefined) {
if (jobConfig !== undefined && dataView !== undefined) {
const resultsField = jobConfig.dest.results_field;
const { fieldTypes } = getIndexFields(jobConfig, needsDestIndexFields);
newColumns.push(
@ -63,7 +63,7 @@ export const useOutlierData = (
return newColumns;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [jobConfig, indexPattern]);
}, [jobConfig, dataView]);
const dataGrid = useExplorationDataGrid(
columns,
@ -95,11 +95,8 @@ export const useOutlierData = (
}, [jobConfig && jobConfig.id, dataGrid.pagination, searchQuery, dataGrid.sortingColumns]);
const dataLoader = useMemo(
() =>
indexPattern !== undefined
? new DataLoader(indexPattern, getToastNotifications())
: undefined,
[indexPattern]
() => (dataView !== undefined ? new DataLoader(dataView, getToastNotifications()) : undefined),
[dataView]
);
const fetchColumnChartsData = async function () {
@ -146,7 +143,7 @@ export const useOutlierData = (
);
const renderCellValue = useRenderCellValue(
indexPattern,
dataView,
dataGrid.pagination,
dataGrid.tableItems,
jobConfig?.dest.results_field ?? DEFAULT_RESULTS_FIELD,

View file

@ -21,12 +21,12 @@ export const DeleteActionModal: FC<DeleteAction> = ({
closeModal,
deleteAndCloseModal,
deleteTargetIndex,
deleteIndexPattern,
indexPatternExists,
deleteDataView,
dataViewExists,
isLoading,
item,
toggleDeleteIndex,
toggleDeleteIndexPattern,
toggleDeleteDataView,
userCanDeleteIndex,
userCanDeleteDataView,
}) => {
@ -77,15 +77,15 @@ export const DeleteActionModal: FC<DeleteAction> = ({
)}
</EuiFlexItem>
<EuiFlexItem>
{userCanDeleteIndex && indexPatternExists && (
{userCanDeleteIndex && dataViewExists && (
<EuiSwitch
data-test-subj="mlAnalyticsJobDeleteIndexPatternSwitch"
data-test-subj="mlAnalyticsJobDeleteDataViewSwitch"
label={i18n.translate('xpack.ml.dataframe.analyticsList.deleteTargetDataViewTitle', {
defaultMessage: 'Delete data view {dataView}',
values: { dataView: indexName },
})}
checked={deleteIndexPattern}
onChange={toggleDeleteIndexPattern}
checked={deleteDataView}
onChange={toggleDeleteDataView}
disabled={userCanDeleteDataView === false}
/>
)}

View file

@ -99,7 +99,7 @@ describe('DeleteAction', () => {
fireEvent.click(deleteButton);
expect(getByTestId('mlAnalyticsJobDeleteModal')).toBeInTheDocument();
expect(queryByTestId('mlAnalyticsJobDeleteIndexSwitch')).toBeNull();
expect(queryByTestId('mlAnalyticsJobDeleteIndexPatternSwitch')).toBeNull();
expect(queryByTestId('mlAnalyticsJobDeleteDataViewSwitch')).toBeNull();
mock.mockRestore();
});

View file

@ -42,10 +42,10 @@ export const useDeleteAction = (canDeleteDataFrameAnalytics: boolean) => {
const [isDeleteJobCheckModalVisible, setDeleteJobCheckModalVisible] = useState<boolean>(false);
const [deleteItem, setDeleteItem] = useState(false);
const [deleteTargetIndex, setDeleteTargetIndex] = useState<boolean>(true);
const [deleteIndexPattern, setDeleteIndexPattern] = useState<boolean>(true);
const [deleteDataView, setDeleteDataView] = useState<boolean>(true);
const [userCanDeleteIndex, setUserCanDeleteIndex] = useState<boolean>(false);
const [userCanDeleteDataView, setUserCanDeleteDataView] = useState<boolean>(false);
const [indexPatternExists, setIndexPatternExists] = useState<boolean>(false);
const [dataViewExists, setDataViewExists] = useState<boolean>(false);
const [isLoading, setIsLoading] = useState<boolean>(false);
const {
@ -57,13 +57,13 @@ export const useDeleteAction = (canDeleteDataFrameAnalytics: boolean) => {
const toastNotificationService = useToastNotificationService();
const checkIndexPatternExists = async () => {
const checkDataViewExists = async () => {
try {
const dv = (await dataViews.getIdsWithTitle()).find(({ title }) => title === indexName);
if (dv !== undefined) {
setIndexPatternExists(true);
setDataViewExists(true);
} else {
setIndexPatternExists(false);
setDataViewExists(false);
}
setIsLoading(false);
} catch (e) {
@ -93,7 +93,7 @@ export const useDeleteAction = (canDeleteDataFrameAnalytics: boolean) => {
capabilities.indexPatterns.save === true;
setUserCanDeleteDataView(canDeleteDataView);
if (canDeleteDataView === false) {
setDeleteIndexPattern(false);
setDeleteDataView(false);
}
} catch (e) {
const error = extractErrorMessage(e);
@ -116,7 +116,7 @@ export const useDeleteAction = (canDeleteDataFrameAnalytics: boolean) => {
setIsLoading(true);
// Check if a data view exists corresponding to current DFA job
// if data view does exist, show it to user
checkIndexPatternExists();
checkDataViewExists();
// Check if an user has permission to delete the index & data view
checkUserIndexPermission();
// eslint-disable-next-line react-hooks/exhaustive-deps
@ -129,12 +129,12 @@ export const useDeleteAction = (canDeleteDataFrameAnalytics: boolean) => {
setModalVisible(false);
if (item !== undefined) {
if ((userCanDeleteIndex && deleteTargetIndex) || (userCanDeleteIndex && deleteIndexPattern)) {
if ((userCanDeleteIndex && deleteTargetIndex) || (userCanDeleteIndex && deleteDataView)) {
deleteAnalyticsAndDestIndex(
item.config,
item.stats,
deleteTargetIndex,
indexPatternExists && deleteIndexPattern,
dataViewExists && deleteDataView,
toastNotificationService
);
} else {
@ -143,7 +143,7 @@ export const useDeleteAction = (canDeleteDataFrameAnalytics: boolean) => {
}
};
const toggleDeleteIndex = () => setDeleteTargetIndex(!deleteTargetIndex);
const toggleDeleteIndexPattern = () => setDeleteIndexPattern(!deleteIndexPattern);
const toggleDeleteDataView = () => setDeleteDataView(!deleteDataView);
const openModal = (newItem: DataFrameAnalyticsListRowEssentials) => {
setItem(newItem);
@ -181,9 +181,9 @@ export const useDeleteAction = (canDeleteDataFrameAnalytics: boolean) => {
closeModal,
deleteAndCloseModal,
deleteTargetIndex,
deleteIndexPattern,
deleteDataView,
deleteItem,
indexPatternExists,
dataViewExists,
isDeleteJobCheckModalVisible,
isModalVisible,
isLoading,
@ -192,7 +192,7 @@ export const useDeleteAction = (canDeleteDataFrameAnalytics: boolean) => {
openModal,
openDeleteJobCheckModal,
toggleDeleteIndex,
toggleDeleteIndexPattern,
toggleDeleteDataView,
userCanDeleteIndex,
userCanDeleteDataView,
};

View file

@ -146,7 +146,7 @@ export const SourceSelection: FC = () => {
type: 'index-pattern',
getIconForSavedObject: () => 'indexPatternApp',
name: i18n.translate(
'xpack.ml.dataFrame.analytics.create.searchSelection.savedObjectType.indexPattern',
'xpack.ml.dataFrame.analytics.create.searchSelection.savedObjectType.dataView',
{
defaultMessage: 'Data view',
}

View file

@ -18,7 +18,7 @@ export enum ACTION {
RESET_FORM,
SET_ADVANCED_EDITOR_RAW_STRING,
SET_FORM_STATE,
SET_INDEX_PATTERN_TITLES,
SET_DATA_VIEW_TITLES,
SET_IS_JOB_CREATED,
SET_IS_JOB_STARTED,
SET_IS_MODAL_BUTTON_DISABLED,
@ -51,9 +51,9 @@ export type Action =
}
| { type: ACTION.SET_FORM_STATE; payload: Partial<State['form']> }
| {
type: ACTION.SET_INDEX_PATTERN_TITLES;
type: ACTION.SET_DATA_VIEW_TITLES;
payload: {
indexPatternsMap: SourceIndexMap;
dataViewsMap: SourceIndexMap;
};
}
| { type: ACTION.SET_IS_JOB_CREATED; isJobCreated: State['isJobCreated'] }

View file

@ -39,7 +39,7 @@ const getMockState = ({
jobIdEmpty: false,
jobIdValid: true,
jobIdExists: false,
createIndexPattern: false,
createDataView: false,
},
jobConfig: {
source: { index },

View file

@ -148,7 +148,7 @@ export const validateNumTopFeatureImportanceValues = (
};
export const validateAdvancedEditor = (state: State): State => {
const { jobIdEmpty, jobIdValid, jobIdExists, jobType, createIndexPattern } = state.form;
const { jobIdEmpty, jobIdValid, jobIdExists, jobType, createDataView } = state.form;
const { jobConfig } = state;
state.advancedEditorMessages = [];
@ -161,8 +161,7 @@ export const validateAdvancedEditor = (state: State): State => {
const destinationIndexName = jobConfig?.dest?.index ?? '';
const destinationIndexNameEmpty = destinationIndexName === '';
const destinationIndexNameValid = isValidIndexName(destinationIndexName);
const destinationIndexPatternTitleExists =
state.indexPatternsMap[destinationIndexName] !== undefined;
const destinationDataViewTitleExists = state.dataViewsMap[destinationIndexName] !== undefined;
const analyzedFields = jobConfig?.analyzed_fields?.includes || [];
@ -294,7 +293,7 @@ export const validateAdvancedEditor = (state: State): State => {
),
message: '',
});
} else if (destinationIndexPatternTitleExists && !createIndexPattern) {
} else if (destinationDataViewTitleExists && !createDataView) {
state.advancedEditorMessages.push({
error: i18n.translate(
'xpack.ml.dataframe.analytics.create.advancedEditorMessage.destinationIndexNameExistsWarn',
@ -360,7 +359,7 @@ export const validateAdvancedEditor = (state: State): State => {
});
}
state.form.destinationIndexPatternTitleExists = destinationIndexPatternTitleExists;
state.form.destinationDataViewTitleExists = destinationDataViewTitleExists;
state.isValid =
includesValid &&
@ -377,7 +376,7 @@ export const validateAdvancedEditor = (state: State): State => {
!dependentVariableEmpty &&
!modelMemoryLimitEmpty &&
(numTopFeatureImportanceValuesValid || jobType === ANALYSIS_CONFIG_TYPE.OUTLIER_DETECTION) &&
(!destinationIndexPatternTitleExists || !createIndexPattern);
(!destinationDataViewTitleExists || !createDataView);
return state;
};
@ -425,8 +424,8 @@ const validateForm = (state: State): State => {
sourceIndexNameValid,
destinationIndexNameEmpty,
destinationIndexNameValid,
destinationIndexPatternTitleExists,
createIndexPattern,
destinationDataViewTitleExists,
createDataView,
dependentVariable,
modelMemoryLimit,
numTopFeatureImportanceValuesValid,
@ -458,7 +457,7 @@ const validateForm = (state: State): State => {
destinationIndexNameValid &&
!dependentVariableEmpty &&
(numTopFeatureImportanceValuesValid || jobType === ANALYSIS_CONFIG_TYPE.OUTLIER_DETECTION) &&
(!destinationIndexPatternTitleExists || !createIndexPattern);
(!destinationDataViewTitleExists || !createDataView);
return state;
};
@ -513,8 +512,8 @@ export function reducer(state: State, action: Action): State {
if (action.payload.destinationIndex !== undefined) {
newFormState.destinationIndexNameEmpty = newFormState.destinationIndex === '';
newFormState.destinationIndexNameValid = isValidIndexName(newFormState.destinationIndex);
newFormState.destinationIndexPatternTitleExists =
state.indexPatternsMap[newFormState.destinationIndex] !== undefined;
newFormState.destinationDataViewTitleExists =
state.dataViewsMap[newFormState.destinationIndex] !== undefined;
}
if (action.payload.jobId !== undefined) {
@ -541,13 +540,13 @@ export function reducer(state: State, action: Action): State {
? validateAdvancedEditor({ ...state, form: newFormState })
: validateForm({ ...state, form: newFormState });
case ACTION.SET_INDEX_PATTERN_TITLES: {
case ACTION.SET_DATA_VIEW_TITLES: {
const newState = {
...state,
...action.payload,
};
newState.form.destinationIndexPatternTitleExists =
newState.indexPatternsMap[newState.form.destinationIndex] !== undefined;
newState.form.destinationDataViewTitleExists =
newState.dataViewsMap[newState.form.destinationIndex] !== undefined;
return newState;
}
@ -591,8 +590,8 @@ export function reducer(state: State, action: Action): State {
formState.destinationIndexNameEmpty = formState.destinationIndex === '';
formState.destinationIndexNameValid = isValidIndexName(formState.destinationIndex || '');
formState.destinationIndexPatternTitleExists =
state.indexPatternsMap[formState.destinationIndex || ''] !== undefined;
formState.destinationDataViewTitleExists =
state.dataViewsMap[formState.destinationIndex || ''] !== undefined;
if (formState.numTopFeatureImportanceValues !== undefined) {
formState.numTopFeatureImportanceValuesValid = validateNumTopFeatureImportanceValues(

View file

@ -35,13 +35,10 @@ export const UNSET_CONFIG_ITEM = '--';
export type EsIndexName = string;
export type DependentVariable = string;
export type IndexPatternTitle = string;
export type DataViewTitle = string;
export type AnalyticsJobType = DataFrameAnalysisConfigType | undefined;
type IndexPatternId = string;
export type SourceIndexMap = Record<
IndexPatternTitle,
{ label: IndexPatternTitle; value: IndexPatternId }
>;
type DataViewId = string;
export type SourceIndexMap = Record<DataViewTitle, { label: DataViewTitle; value: DataViewId }>;
export interface FormMessage {
error?: string;
@ -55,7 +52,7 @@ export interface State {
form: {
alpha: undefined | number;
computeFeatureInfluence: string;
createIndexPattern: boolean;
createDataView: boolean;
classAssignmentObjective: undefined | string;
dependentVariable: DependentVariable;
description: string;
@ -63,7 +60,7 @@ export interface State {
destinationIndexNameExists: boolean;
destinationIndexNameEmpty: boolean;
destinationIndexNameValid: boolean;
destinationIndexPatternTitleExists: boolean;
destinationDataViewTitleExists: boolean;
downsampleFactor: undefined | number;
earlyStoppingEnabled: undefined | boolean;
eta: undefined | number;
@ -120,7 +117,7 @@ export interface State {
useEstimatedMml: boolean;
};
disabled: boolean;
indexPatternsMap: SourceIndexMap;
dataViewsMap: SourceIndexMap;
isAdvancedEditorEnabled: boolean;
isAdvancedEditorValidJson: boolean;
hasSwitchedToEditor: boolean;
@ -141,7 +138,7 @@ export const getInitialState = (): State => ({
form: {
alpha: undefined,
computeFeatureInfluence: 'true',
createIndexPattern: true,
createDataView: true,
classAssignmentObjective: undefined,
dependentVariable: '',
description: '',
@ -149,7 +146,7 @@ export const getInitialState = (): State => ({
destinationIndexNameExists: false,
destinationIndexNameEmpty: true,
destinationIndexNameValid: false,
destinationIndexPatternTitleExists: false,
destinationDataViewTitleExists: false,
earlyStoppingEnabled: undefined,
downsampleFactor: undefined,
eta: undefined,
@ -210,7 +207,7 @@ export const getInitialState = (): State => ({
!mlNodesAvailable() ||
!checkPermission('canCreateDataFrameAnalytics') ||
!checkPermission('canStartStopDataFrameAnalytics'),
indexPatternsMap: {},
dataViewsMap: {},
isAdvancedEditorEnabled: false,
isAdvancedEditorValidJson: true,
hasSwitchedToEditor: false,

View file

@ -59,7 +59,7 @@ export const useCreateAnalyticsForm = (): CreateAnalyticsFormProps => {
const { refresh } = useRefreshAnalyticsList();
const { form, jobConfig, isAdvancedEditorEnabled } = state;
const { createIndexPattern, jobId } = form;
const { createDataView, jobId } = form;
let { destinationIndex } = form;
const addRequestMessage = (requestMessage: FormMessage) =>
@ -73,8 +73,8 @@ export const useCreateAnalyticsForm = (): CreateAnalyticsFormProps => {
const setAdvancedEditorRawString = (advancedEditorRawString: string) =>
dispatch({ type: ACTION.SET_ADVANCED_EDITOR_RAW_STRING, advancedEditorRawString });
const setIndexPatternTitles = (payload: { indexPatternsMap: SourceIndexMap }) =>
dispatch({ type: ACTION.SET_INDEX_PATTERN_TITLES, payload });
const setDataViewTitles = (payload: { dataViewsMap: SourceIndexMap }) =>
dispatch({ type: ACTION.SET_DATA_VIEW_TITLES, payload });
const setIsJobCreated = (isJobCreated: boolean) =>
dispatch({ type: ACTION.SET_IS_JOB_CREATED, isJobCreated });
@ -110,7 +110,7 @@ export const useCreateAnalyticsForm = (): CreateAnalyticsFormProps => {
),
});
setIsJobCreated(true);
if (createIndexPattern) {
if (createDataView) {
createKibanaDataView(destinationIndex, dataViews, form.timeFieldName, addRequestMessage);
}
refresh();
@ -132,17 +132,17 @@ export const useCreateAnalyticsForm = (): CreateAnalyticsFormProps => {
const prepareFormValidation = async () => {
try {
// Set the existing data view names.
const indexPatternsMap: SourceIndexMap = {};
const dataViewsMap: SourceIndexMap = {};
const savedObjects = (await dataViews.getCache()) || [];
savedObjects.forEach((obj) => {
const title = obj?.attributes?.title;
if (title !== undefined) {
const id = obj?.id || '';
indexPatternsMap[title] = { label: title, value: id };
dataViewsMap[title] = { label: title, value: id };
}
});
setIndexPatternTitles({
indexPatternsMap,
setDataViewTitles({
dataViewsMap,
});
} catch (e) {
addRequestMessage({

View file

@ -48,7 +48,7 @@ export const deleteAnalyticsAndDestIndex = async (
analyticsConfig: DataFrameAnalyticsListRow['config'],
analyticsStats: DataFrameAnalyticsListRow['stats'],
deleteDestIndex: boolean,
deleteDestIndexPattern: boolean,
deleteDestDataView: boolean,
toastNotificationService: ToastNotificationService
) => {
const destinationIndex = analyticsConfig.dest.index;
@ -59,7 +59,7 @@ export const deleteAnalyticsAndDestIndex = async (
const status = await ml.dataFrameAnalytics.deleteDataFrameAnalyticsAndDestIndex(
analyticsConfig.id,
deleteDestIndex,
deleteDestIndexPattern
deleteDestDataView
);
if (status.analyticsJobDeleted?.success) {
toastNotificationService.displaySuccessToast(
@ -97,7 +97,7 @@ export const deleteAnalyticsAndDestIndex = async (
);
}
if (status.destIndexPatternDeleted?.success) {
if (status.destDataViewDeleted?.success) {
toastNotificationService.displaySuccessToast(
i18n.translate(
'xpack.ml.dataframe.analyticsList.deleteAnalyticsWithDataViewSuccessMessage',
@ -108,8 +108,8 @@ export const deleteAnalyticsAndDestIndex = async (
)
);
}
if (status.destIndexPatternDeleted?.error) {
const error = extractErrorMessage(status.destIndexPatternDeleted.error);
if (status.destDataViewDeleted?.error) {
const error = extractErrorMessage(status.destDataViewDeleted.error);
toastNotificationService.displayDangerToast(
i18n.translate('xpack.ml.dataframe.analyticsList.deleteAnalyticsWithDataViewErrorMessage', {
defaultMessage: 'An error occurred deleting data view {destinationIndex}: {error}',

View file

@ -49,7 +49,7 @@ export interface DeleteDataFrameAnalyticsWithIndexResponse {
acknowledged: boolean;
analyticsJobDeleted: DeleteDataFrameAnalyticsWithIndexStatus;
destIndexDeleted: DeleteDataFrameAnalyticsWithIndexStatus;
destIndexPatternDeleted: DeleteDataFrameAnalyticsWithIndexStatus;
destDataViewDeleted: DeleteDataFrameAnalyticsWithIndexStatus;
}
export interface JobsExistsResponse {
@ -152,11 +152,11 @@ export const dataFrameAnalyticsApiProvider = (httpService: HttpService) => ({
deleteDataFrameAnalyticsAndDestIndex(
analyticsId: string,
deleteDestIndex: boolean,
deleteDestIndexPattern: boolean
deleteDestDataView: boolean
) {
return httpService.http<DeleteDataFrameAnalyticsWithIndexResponse>({
path: `${ML_INTERNAL_BASE_PATH}/data_frame/analytics/${analyticsId}`,
query: { deleteDestIndex, deleteDestIndexPattern },
query: { deleteDestIndex, deleteDestDataView },
method: 'DELETE',
version: '1',
});

View file

@ -129,6 +129,6 @@ export function timeBasedIndexCheck(dataView: DataView, showNotification = false
* Returns true if the data view index pattern contains a :
* which means it is cross-cluster
*/
export function isCcsIndexPattern(dataViewIndexPattern: string) {
return dataViewIndexPattern.includes(':');
export function isCcsIndexPattern(indexPattern: string) {
return indexPattern.includes(':');
}

View file

@ -9,7 +9,7 @@ import { DataViewsService } from '@kbn/data-views-plugin/common';
export class DataViewHandler {
constructor(private dataViewService: DataViewsService) {}
// returns a id based on an index pattern name
// returns a id based on an data view name
async getDataViewId(indexName: string) {
const dv = (await this.dataViewService.find(indexName)).find(
({ title }) => title === indexName

View file

@ -18,35 +18,35 @@ import { wrapError } from '../client/error_wrapper';
import { analyticsAuditMessagesProvider } from '../models/data_frame_analytics/analytics_audit_messages';
import type { RouteInitialization } from '../types';
import {
dataAnalyticsJobConfigSchema,
dataAnalyticsJobUpdateSchema,
dataAnalyticsEvaluateSchema,
dataAnalyticsExplainSchema,
analyticsIdSchema,
analyticsMapQuerySchema,
dataFrameAnalyticsJobConfigSchema,
dataFrameAnalyticsJobUpdateSchema,
dataFrameAnalyticsEvaluateSchema,
dataFrameAnalyticsExplainSchema,
dataFrameAnalyticsIdSchema,
dataFrameAnalyticsMapQuerySchema,
stopsDataFrameAnalyticsJobQuerySchema,
deleteDataFrameAnalyticsJobSchema,
jobsExistSchema,
analyticsQuerySchema,
analyticsNewJobCapsParamsSchema,
analyticsNewJobCapsQuerySchema,
} from './schemas/data_analytics_schema';
dataFrameAnalyticsJobsExistSchema,
dataFrameAnalyticsQuerySchema,
dataFrameAnalyticsNewJobCapsParamsSchema,
dataFrameAnalyticsNewJobCapsQuerySchema,
} from './schemas/data_frame_analytics_schema';
import type { ExtendAnalyticsMapArgs } from '../models/data_frame_analytics/types';
import { DataViewHandler } from '../models/data_frame_analytics/index_patterns';
import { DataViewHandler } from '../models/data_frame_analytics/data_view_handler';
import { AnalyticsManager } from '../models/data_frame_analytics/analytics_manager';
import { validateAnalyticsJob } from '../models/data_frame_analytics/validation';
import { fieldServiceProvider } from '../models/job_service/new_job_caps/field_service';
import { getAuthorizationHeader } from '../lib/request_authorization';
import type { MlClient } from '../lib/ml_client';
function getDataViewId(dataViewsService: DataViewsService, patternName: string) {
async function getDataViewId(dataViewsService: DataViewsService, patternName: string) {
const iph = new DataViewHandler(dataViewsService);
return iph.getDataViewId(patternName);
return await iph.getDataViewId(patternName);
}
function deleteDestDataViewById(dataViewsService: DataViewsService, dataViewId: string) {
async function deleteDestDataViewById(dataViewsService: DataViewsService, dataViewId: string) {
const iph = new DataViewHandler(dataViewsService);
return iph.deleteDataViewById(dataViewId);
return await iph.deleteDataViewById(dataViewId);
}
function getExtendedMap(
@ -144,7 +144,7 @@ export function dataFrameAnalyticsRoutes(
version: '1',
validate: {
request: {
query: analyticsQuerySchema,
query: dataFrameAnalyticsQuerySchema,
},
},
},
@ -185,8 +185,8 @@ export function dataFrameAnalyticsRoutes(
version: '1',
validate: {
request: {
params: analyticsIdSchema,
query: analyticsQuerySchema,
params: dataFrameAnalyticsIdSchema,
query: dataFrameAnalyticsQuerySchema,
},
},
},
@ -262,7 +262,7 @@ export function dataFrameAnalyticsRoutes(
version: '1',
validate: {
request: {
params: analyticsIdSchema,
params: dataFrameAnalyticsIdSchema,
},
},
},
@ -305,8 +305,8 @@ export function dataFrameAnalyticsRoutes(
version: '1',
validate: {
request: {
params: analyticsIdSchema,
body: dataAnalyticsJobConfigSchema,
params: dataFrameAnalyticsIdSchema,
body: dataFrameAnalyticsJobConfigSchema,
},
},
},
@ -352,7 +352,7 @@ export function dataFrameAnalyticsRoutes(
version: '1',
validate: {
request: {
body: dataAnalyticsEvaluateSchema,
body: dataFrameAnalyticsEvaluateSchema,
},
},
},
@ -397,7 +397,7 @@ export function dataFrameAnalyticsRoutes(
version: '1',
validate: {
request: {
body: dataAnalyticsExplainSchema,
body: dataFrameAnalyticsExplainSchema,
},
},
},
@ -440,7 +440,7 @@ export function dataFrameAnalyticsRoutes(
version: '1',
validate: {
request: {
params: analyticsIdSchema,
params: dataFrameAnalyticsIdSchema,
query: deleteDataFrameAnalyticsJobSchema,
},
},
@ -449,11 +449,11 @@ export function dataFrameAnalyticsRoutes(
async ({ mlClient, client, request, response, getDataViewsService }) => {
try {
const { analyticsId } = request.params;
const { deleteDestIndex, deleteDestIndexPattern } = request.query;
const { deleteDestIndex, deleteDestDataView } = request.query;
let destinationIndex: string | undefined;
const analyticsJobDeleted: DeleteDataFrameAnalyticsWithIndexStatus = { success: false };
const destIndexDeleted: DeleteDataFrameAnalyticsWithIndexStatus = { success: false };
const destIndexPatternDeleted: DeleteDataFrameAnalyticsWithIndexStatus = {
const destDataViewDeleted: DeleteDataFrameAnalyticsWithIndexStatus = {
success: false,
};
@ -473,7 +473,7 @@ export function dataFrameAnalyticsRoutes(
return response.customError(wrapError(e));
}
if (deleteDestIndex || deleteDestIndexPattern) {
if (deleteDestIndex || deleteDestDataView) {
// If user checks box to delete the destinationIndex associated with the job
if (destinationIndex && deleteDestIndex) {
// Verify if user has privilege to delete the destination index
@ -494,16 +494,16 @@ export function dataFrameAnalyticsRoutes(
}
// Delete the index pattern if there's an index pattern that matches the name of dest index
if (destinationIndex && deleteDestIndexPattern) {
if (destinationIndex && deleteDestDataView) {
try {
const dataViewsService = await getDataViewsService();
const dataViewId = await getDataViewId(dataViewsService, destinationIndex);
if (dataViewId) {
await deleteDestDataViewById(dataViewsService, dataViewId);
}
destIndexPatternDeleted.success = true;
destDataViewDeleted.success = true;
} catch (deleteDestIndexPatternError) {
destIndexPatternDeleted.error = deleteDestIndexPatternError;
destDataViewDeleted.error = deleteDestIndexPatternError;
}
}
}
@ -521,7 +521,7 @@ export function dataFrameAnalyticsRoutes(
const results = {
analyticsJobDeleted,
destIndexDeleted,
destIndexPatternDeleted,
destDataViewDeleted,
};
return response.ok({
body: results,
@ -555,7 +555,7 @@ export function dataFrameAnalyticsRoutes(
version: '1',
validate: {
request: {
params: analyticsIdSchema,
params: dataFrameAnalyticsIdSchema,
},
},
},
@ -597,7 +597,7 @@ export function dataFrameAnalyticsRoutes(
version: '1',
validate: {
request: {
params: analyticsIdSchema,
params: dataFrameAnalyticsIdSchema,
query: stopsDataFrameAnalyticsJobQuerySchema,
},
},
@ -640,8 +640,8 @@ export function dataFrameAnalyticsRoutes(
version: '1',
validate: {
request: {
params: analyticsIdSchema,
body: dataAnalyticsJobUpdateSchema,
params: dataFrameAnalyticsIdSchema,
body: dataFrameAnalyticsJobUpdateSchema,
},
},
},
@ -686,7 +686,7 @@ export function dataFrameAnalyticsRoutes(
version: '1',
validate: {
request: {
params: analyticsIdSchema,
params: dataFrameAnalyticsIdSchema,
},
},
},
@ -728,7 +728,7 @@ export function dataFrameAnalyticsRoutes(
version: '1',
validate: {
request: {
body: jobsExistSchema,
body: dataFrameAnalyticsJobsExistSchema,
},
},
},
@ -785,8 +785,8 @@ export function dataFrameAnalyticsRoutes(
version: '1',
validate: {
request: {
params: analyticsIdSchema,
query: analyticsMapQuerySchema,
params: dataFrameAnalyticsIdSchema,
query: dataFrameAnalyticsMapQuerySchema,
},
},
},
@ -851,8 +851,8 @@ export function dataFrameAnalyticsRoutes(
version: '1',
validate: {
request: {
params: analyticsNewJobCapsParamsSchema,
query: analyticsNewJobCapsQuerySchema,
params: dataFrameAnalyticsNewJobCapsParamsSchema,
query: dataFrameAnalyticsNewJobCapsQuerySchema,
},
},
},
@ -906,7 +906,7 @@ export function dataFrameAnalyticsRoutes(
version: '1',
validate: {
request: {
body: dataAnalyticsJobConfigSchema,
body: dataFrameAnalyticsJobConfigSchema,
},
},
},

View file

@ -8,7 +8,7 @@
import { schema } from '@kbn/config-schema';
import { runtimeMappingsSchema } from './runtime_mappings_schema';
export const dataAnalyticsJobConfigSchema = schema.object({
export const dataFrameAnalyticsJobConfigSchema = schema.object({
description: schema.maybe(schema.string()),
_meta: schema.maybe(schema.object({}, { unknowns: 'allow' })),
dest: schema.object({
@ -35,7 +35,7 @@ export const dataAnalyticsJobConfigSchema = schema.object({
max_num_threads: schema.maybe(schema.number()),
});
export const dataAnalyticsEvaluateSchema = schema.object({
export const dataFrameAnalyticsEvaluateSchema = schema.object({
index: schema.string(),
query: schema.maybe(schema.any()),
evaluation: schema.maybe(
@ -47,7 +47,7 @@ export const dataAnalyticsEvaluateSchema = schema.object({
),
});
export const dataAnalyticsExplainSchema = schema.object({
export const dataFrameAnalyticsExplainSchema = schema.object({
description: schema.maybe(schema.string()),
dest: schema.maybe(schema.any()),
/** Source */
@ -63,14 +63,14 @@ export const dataAnalyticsExplainSchema = schema.object({
_meta: schema.maybe(schema.object({}, { unknowns: 'allow' })),
});
export const analyticsIdSchema = schema.object({
export const dataFrameAnalyticsIdSchema = schema.object({
/**
* Analytics ID
*/
analyticsId: schema.string(),
});
export const analyticsQuerySchema = schema.object({
export const dataFrameAnalyticsQuerySchema = schema.object({
/**
* Analytics Query
*/
@ -83,10 +83,10 @@ export const deleteDataFrameAnalyticsJobSchema = schema.object({
* Analytics Destination Index
*/
deleteDestIndex: schema.maybe(schema.boolean()),
deleteDestIndexPattern: schema.maybe(schema.boolean()),
deleteDestDataView: schema.maybe(schema.boolean()),
});
export const dataAnalyticsJobUpdateSchema = schema.object({
export const dataFrameAnalyticsJobUpdateSchema = schema.object({
description: schema.maybe(schema.string()),
model_memory_limit: schema.maybe(schema.string()),
allow_lazy_start: schema.maybe(schema.boolean()),
@ -98,17 +98,19 @@ export const stopsDataFrameAnalyticsJobQuerySchema = schema.object({
force: schema.maybe(schema.boolean()),
});
export const jobsExistSchema = schema.object({
export const dataFrameAnalyticsJobsExistSchema = schema.object({
analyticsIds: schema.arrayOf(schema.string()),
allSpaces: schema.maybe(schema.boolean()),
});
export const analyticsMapQuerySchema = schema.maybe(
export const dataFrameAnalyticsMapQuerySchema = schema.maybe(
schema.object({ treatAsRoot: schema.maybe(schema.any()), type: schema.maybe(schema.string()) })
);
export const analyticsNewJobCapsParamsSchema = schema.object({ indexPattern: schema.string() });
export const dataFrameAnalyticsNewJobCapsParamsSchema = schema.object({
indexPattern: schema.string(),
});
export const analyticsNewJobCapsQuerySchema = schema.maybe(
export const dataFrameAnalyticsNewJobCapsQuerySchema = schema.maybe(
schema.object({ rollup: schema.maybe(schema.string()) })
);

View file

@ -17,7 +17,7 @@ import {
getFieldType,
getDataGridSchemaFromKibanaFieldType,
getDataGridSchemaFromESFieldType,
getFieldsFromKibanaIndexPattern,
getFieldsFromKibanaDataView,
showDataGridColumnChartErrorMessageToast,
useDataGrid,
useRenderCellValue,
@ -140,7 +140,7 @@ export const useIndexData = (
allPopulatedFields = [...new Set(docs.map(Object.keys).flat(1))];
}
const allDataViewFields = getFieldsFromKibanaIndexPattern(dataView);
const allDataViewFields = getFieldsFromKibanaDataView(dataView);
return allPopulatedFields.filter((d) => allDataViewFields.includes(d)).sort();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [dataViewFieldsData, populatedFields]);

View file

@ -25329,7 +25329,7 @@
"xpack.ml.dataFrame.analytics.create.searchSelection.CcsErrorCallOutTitle": "Les vues de données utilisant la recherche inter-clusters ne sont pas prises en charge.",
"xpack.ml.dataFrame.analytics.create.searchSelection.errorGettingDataViewTitle": "Erreur lors du chargement de la vue de données utilisée par la recherche enregistrée",
"xpack.ml.dataFrame.analytics.create.searchSelection.notFoundLabel": "Aucun recherche enregistrée ni aucun index correspondants n'ont été trouvés.",
"xpack.ml.dataFrame.analytics.create.searchSelection.savedObjectType.indexPattern": "Vue de données",
"xpack.ml.dataFrame.analytics.create.searchSelection.savedObjectType.dataView": "Vue de données",
"xpack.ml.dataFrame.analytics.create.searchSelection.savedObjectType.search": "Recherche enregistrée",
"xpack.ml.dataframe.analytics.create.shouldCreateDataViewMessage": "Vous ne pourrez peut-être pas visualiser les résultats de la tâche si aucune vue de données n'est créée pour l'index de destination.",
"xpack.ml.dataframe.analytics.create.softTreeDepthLimitInputAriaLabel": "Les arbres de décision dépassant cette profondeur sont pénalisés dans les calculs de perte.",

View file

@ -25328,7 +25328,7 @@
"xpack.ml.dataFrame.analytics.create.searchSelection.CcsErrorCallOutTitle": "クラスター横断検索を使用するデータビューはサポートされていません。",
"xpack.ml.dataFrame.analytics.create.searchSelection.errorGettingDataViewTitle": "保存された検索で使用されているデータビューの読み込みエラー",
"xpack.ml.dataFrame.analytics.create.searchSelection.notFoundLabel": "一致インデックスまたは保存した検索が見つかりません。",
"xpack.ml.dataFrame.analytics.create.searchSelection.savedObjectType.indexPattern": "データビュー",
"xpack.ml.dataFrame.analytics.create.searchSelection.savedObjectType.dataView": "データビュー",
"xpack.ml.dataFrame.analytics.create.searchSelection.savedObjectType.search": "保存検索",
"xpack.ml.dataframe.analytics.create.shouldCreateDataViewMessage": "デスティネーションインデックスのデータビューが作成されていない場合は、ジョブ結果を表示できないことがあります。",
"xpack.ml.dataframe.analytics.create.softTreeDepthLimitInputAriaLabel": "この深さを超える決定木は、損失計算でペナルティがあります。",

View file

@ -25327,7 +25327,7 @@
"xpack.ml.dataFrame.analytics.create.searchSelection.CcsErrorCallOutTitle": "不支持使用跨集群搜索的数据视图。",
"xpack.ml.dataFrame.analytics.create.searchSelection.errorGettingDataViewTitle": "加载已保存搜索所使用的数据视图时出错",
"xpack.ml.dataFrame.analytics.create.searchSelection.notFoundLabel": "未找到匹配的索引或已保存搜索。",
"xpack.ml.dataFrame.analytics.create.searchSelection.savedObjectType.indexPattern": "数据视图",
"xpack.ml.dataFrame.analytics.create.searchSelection.savedObjectType.dataView": "数据视图",
"xpack.ml.dataFrame.analytics.create.searchSelection.savedObjectType.search": "已保存搜索",
"xpack.ml.dataframe.analytics.create.shouldCreateDataViewMessage": "如果没有为目标索引创建数据视图,则可能无法查看作业结果。",
"xpack.ml.dataframe.analytics.create.softTreeDepthLimitInputAriaLabel": "超过此深度的决策树将在损失计算中被罚分。",

View file

@ -148,13 +148,13 @@ export default ({ getService }: FtrProviderContext) => {
expect(body.analyticsJobDeleted.success).to.eql(true);
expect(body.destIndexDeleted.success).to.eql(true);
expect(body.destIndexPatternDeleted.success).to.eql(false);
expect(body.destDataViewDeleted.success).to.eql(false);
await ml.api.waitForDataFrameAnalyticsJobNotToExist(analyticsId);
await ml.api.assertIndicesNotToExist(destinationIndex);
});
});
describe('with deleteDestIndexPattern setting', function () {
describe('with deleteDestDataView setting', function () {
const analyticsId = `${jobId}_3`;
const destinationIndex = generateDestinationIndex(analyticsId);
@ -170,20 +170,20 @@ export default ({ getService }: FtrProviderContext) => {
it('should delete job and data view by id', async () => {
const { body, status } = await supertest
.delete(`/internal/ml/data_frame/analytics/${analyticsId}`)
.query({ deleteDestIndexPattern: true })
.query({ deleteDestDataView: true })
.auth(USER.ML_POWERUSER, ml.securityCommon.getPasswordForUser(USER.ML_POWERUSER))
.set(getCommonRequestHeader('1'));
ml.api.assertResponseStatusCode(200, status, body);
expect(body.analyticsJobDeleted.success).to.eql(true);
expect(body.destIndexDeleted.success).to.eql(false);
expect(body.destIndexPatternDeleted.success).to.eql(true);
expect(body.destDataViewDeleted.success).to.eql(true);
await ml.api.waitForDataFrameAnalyticsJobNotToExist(analyticsId);
await ml.testResources.assertDataViewNotExist(destinationIndex);
});
});
describe('with deleteDestIndex & deleteDestIndexPattern setting', function () {
describe('with deleteDestIndex & deleteDestDataView setting', function () {
const analyticsId = `${jobId}_4`;
const destinationIndex = generateDestinationIndex(analyticsId);
@ -202,14 +202,14 @@ export default ({ getService }: FtrProviderContext) => {
it('should delete job, target index, and data view by id', async () => {
const { body, status } = await supertest
.delete(`/internal/ml/data_frame/analytics/${analyticsId}`)
.query({ deleteDestIndex: true, deleteDestIndexPattern: true })
.query({ deleteDestIndex: true, deleteDestDataView: true })
.auth(USER.ML_POWERUSER, ml.securityCommon.getPasswordForUser(USER.ML_POWERUSER))
.set(getCommonRequestHeader('1'));
ml.api.assertResponseStatusCode(200, status, body);
expect(body.analyticsJobDeleted.success).to.eql(true);
expect(body.destIndexDeleted.success).to.eql(true);
expect(body.destIndexPatternDeleted.success).to.eql(true);
expect(body.destDataViewDeleted.success).to.eql(true);
await ml.api.waitForDataFrameAnalyticsJobNotToExist(analyticsId);
await ml.api.assertIndicesNotToExist(destinationIndex);
await ml.testResources.assertDataViewNotExist(destinationIndex);

View file

@ -17,7 +17,7 @@ import {
const testDiscoverCustomUrl: DiscoverUrlConfig = {
label: 'Show data',
indexPattern: 'ft_bank_marketing',
indexName: 'ft_bank_marketing',
queryEntityFieldNames: ['day'],
timeRange: TIME_RANGE_TYPE.AUTO,
};
@ -76,7 +76,7 @@ export default function ({ getService }: FtrProviderContext) {
dependentVariable: 'y',
trainingPercent: 20,
modelMemory: '60mb',
createIndexPattern: true,
createDataView: true,
fieldStatsEntries: [
{
fieldName: 'age',
@ -339,9 +339,7 @@ export default function ({ getService }: FtrProviderContext) {
await ml.testExecution.logTestStep('sets the create data view switch');
await ml.dataFrameAnalyticsCreation.assertCreateDataViewSwitchExists();
await ml.dataFrameAnalyticsCreation.setCreateDataViewSwitchState(
testData.createIndexPattern
);
await ml.dataFrameAnalyticsCreation.setCreateDataViewSwitchState(testData.createDataView);
});
it('runs the analytics job and displays it correctly in the job list', async () => {

View file

@ -19,7 +19,7 @@ export default function ({ getService }: FtrProviderContext) {
const testDataList: Array<{
suiteTitle: string;
archive: string;
indexPattern: { name: string; timeField: string };
dataView: { name: string; timeField: string };
job: DeepPartial<DataFrameAnalyticsConfig>;
}> = (() => {
const timestamp = Date.now();
@ -28,7 +28,7 @@ export default function ({ getService }: FtrProviderContext) {
{
suiteTitle: 'classification job supported by the form',
archive: 'x-pack/test/functional/es_archives/ml/bm_classification',
indexPattern: { name: 'ft_bank_marketing', timeField: '@timestamp' },
dataView: { name: 'ft_bank_marketing', timeField: '@timestamp' },
job: {
id: `bm_1_${timestamp}`,
description:
@ -63,7 +63,7 @@ export default function ({ getService }: FtrProviderContext) {
{
suiteTitle: 'outlier detection job supported by the form',
archive: 'x-pack/test/functional/es_archives/ml/ihp_outlier',
indexPattern: { name: 'ft_ihp_outlier', timeField: '@timestamp' },
dataView: { name: 'ft_ihp_outlier', timeField: '@timestamp' },
job: {
id: `ihp_1_${timestamp}`,
description: 'This is the job description',
@ -92,7 +92,7 @@ export default function ({ getService }: FtrProviderContext) {
{
suiteTitle: 'regression job supported by the form',
archive: 'x-pack/test/functional/es_archives/ml/egs_regression',
indexPattern: { name: 'ft_egs_regression', timeField: '@timestamp' },
dataView: { name: 'ft_egs_regression', timeField: '@timestamp' },
job: {
id: `egs_1_${timestamp}`,
description: 'This is the job description',
@ -142,8 +142,8 @@ export default function ({ getService }: FtrProviderContext) {
before(async () => {
await esArchiver.loadIfNeeded(testData.archive);
await ml.testResources.createDataViewIfNeeded(
testData.indexPattern.name,
testData.indexPattern.timeField
testData.dataView.name,
testData.dataView.timeField
);
await ml.api.createDataFrameAnalyticsJob(testData.job as DataFrameAnalyticsConfig);
@ -159,7 +159,7 @@ export default function ({ getService }: FtrProviderContext) {
await ml.api.deleteIndices(testData.job.dest!.index as string);
await ml.testResources.deleteDataViewByTitle(testData.job.dest!.index as string);
await ml.testResources.deleteDataViewByTitle(cloneDestIndex);
await ml.testResources.deleteDataViewByTitle(testData.indexPattern.name);
await ml.testResources.deleteDataViewByTitle(testData.dataView.name);
});
it('opens the existing job in the data frame analytics job wizard', async () => {

View file

@ -15,7 +15,7 @@ import {
const testDiscoverCustomUrl: DiscoverUrlConfig = {
label: 'Show data',
indexPattern: 'ft_farequote',
indexName: 'ft_farequote',
queryEntityFieldNames: ['airline'],
timeRange: TIME_RANGE_TYPE.AUTO,
};

View file

@ -17,7 +17,7 @@ import {
const testDiscoverCustomUrl: DiscoverUrlConfig = {
label: 'Show data',
indexPattern: 'ft_ihp_outlier',
indexName: 'ft_ihp_outlier',
queryEntityFieldNames: ['SaleType'],
timeRange: TIME_RANGE_TYPE.AUTO,
};
@ -83,7 +83,7 @@ export default function ({ getService }: FtrProviderContext) {
},
},
modelMemory: '5mb',
createIndexPattern: true,
createDataView: true,
advancedEditorContent: [
'{',
' "description": "Outlier detection job based on ft_ihp_outlier dataset with runtime fields",',
@ -325,9 +325,7 @@ export default function ({ getService }: FtrProviderContext) {
await ml.testExecution.logTestStep('sets the create data view switch');
await ml.dataFrameAnalyticsCreation.assertCreateDataViewSwitchExists();
await ml.dataFrameAnalyticsCreation.setCreateDataViewSwitchState(
testData.createIndexPattern
);
await ml.dataFrameAnalyticsCreation.setCreateDataViewSwitchState(testData.createDataView);
});
it('runs the analytics job and displays it correctly in the job list', async () => {

View file

@ -63,7 +63,7 @@ export default function ({ getService }: FtrProviderContext) {
},
},
modelMemory: '1mb',
createIndexPattern: true,
createDataView: true,
expected: {
source: 'ft_farequote_small',
histogramCharts: [
@ -140,7 +140,7 @@ export default function ({ getService }: FtrProviderContext) {
},
},
modelMemory: '65mb',
createIndexPattern: true,
createDataView: true,
expected: {
source: 'ft_farequote_small',
histogramCharts: [
@ -217,7 +217,7 @@ export default function ({ getService }: FtrProviderContext) {
},
},
modelMemory: '65mb',
createIndexPattern: true,
createDataView: true,
expected: {
source: 'ft_farequote_small',
histogramCharts: [
@ -295,7 +295,7 @@ export default function ({ getService }: FtrProviderContext) {
},
},
modelMemory: '65mb',
createIndexPattern: true,
createDataView: true,
expected: {
source: 'ft_farequote_small',
histogramCharts: [
@ -464,9 +464,7 @@ export default function ({ getService }: FtrProviderContext) {
await ml.testExecution.logTestStep('sets the create data view switch');
await ml.dataFrameAnalyticsCreation.assertCreateDataViewSwitchExists();
await ml.dataFrameAnalyticsCreation.setCreateDataViewSwitchState(
testData.createIndexPattern
);
await ml.dataFrameAnalyticsCreation.setCreateDataViewSwitchState(testData.createDataView);
});
it('runs the analytics job and displays it correctly in the job list', async () => {

View file

@ -36,7 +36,7 @@ export default function ({ getService }: FtrProviderContext) {
const testDiscoverCustomUrl: DiscoverUrlConfig = {
label: 'Show data',
indexPattern: 'ft_egs_regression',
indexName: 'ft_egs_regression',
queryEntityFieldNames: ['stabf'],
timeRange: TIME_RANGE_TYPE.AUTO,
};
@ -90,7 +90,7 @@ export default function ({ getService }: FtrProviderContext) {
dependentVariable: 'stab',
trainingPercent: 20,
modelMemory: '20mb',
createIndexPattern: true,
createDataView: true,
advancedEditorContent: [
'{',
' "description": "Regression job based on ft_egs_regression dataset with runtime fields",',
@ -340,9 +340,7 @@ export default function ({ getService }: FtrProviderContext) {
await ml.testExecution.logTestStep('sets the create data view switch');
await ml.dataFrameAnalyticsCreation.assertCreateDataViewSwitchExists();
await ml.dataFrameAnalyticsCreation.setCreateDataViewSwitchState(
testData.createIndexPattern
);
await ml.dataFrameAnalyticsCreation.setCreateDataViewSwitchState(testData.createDataView);
});
it('runs the analytics job and displays it correctly in the job list', async () => {

View file

@ -73,7 +73,7 @@ export default function ({ getService }: FtrProviderContext) {
dependentVariable: 'responsetime',
trainingPercent: 20,
modelMemory: '20mb',
createIndexPattern: true,
createDataView: true,
expected: {
source: 'ft_farequote_small',
runtimeFieldsEditorContent: ['{', ' "uppercase_airline": {', ' "type": "keyword",'],
@ -161,7 +161,7 @@ export default function ({ getService }: FtrProviderContext) {
dependentVariable: 'responsetime',
trainingPercent: 20,
modelMemory: '20mb',
createIndexPattern: true,
createDataView: true,
expected: {
source: 'ft_farequote_small',
runtimeFieldsEditorContent: ['{', ' "uppercase_airline": {', ' "type": "keyword",'],
@ -249,7 +249,7 @@ export default function ({ getService }: FtrProviderContext) {
dependentVariable: 'responsetime',
trainingPercent: 20,
modelMemory: '20mb',
createIndexPattern: true,
createDataView: true,
expected: {
source: 'ft_farequote_small',
runtimeFieldsEditorContent: ['{', ' "uppercase_airline": {', ' "type": "keyword",'],
@ -331,7 +331,7 @@ export default function ({ getService }: FtrProviderContext) {
dependentVariable: 'responsetime',
trainingPercent: 20,
modelMemory: '20mb',
createIndexPattern: true,
createDataView: true,
expected: {
source: 'ft_farequote_small',
runtimeFieldsEditorContent: ['{', ' "uppercase_airline": {', ' "type": "keyword",'],
@ -499,9 +499,7 @@ export default function ({ getService }: FtrProviderContext) {
await ml.testExecution.logTestStep('sets the create data view switch');
await ml.dataFrameAnalyticsCreation.assertCreateDataViewSwitchExists();
await ml.dataFrameAnalyticsCreation.setCreateDataViewSwitchState(
testData.createIndexPattern
);
await ml.dataFrameAnalyticsCreation.setCreateDataViewSwitchState(testData.createDataView);
});
it('runs the analytics job and displays it correctly in the job list', async () => {

View file

@ -18,7 +18,7 @@ export default function ({ getService }: FtrProviderContext) {
const testDataList: Array<{
suiteTitle: string;
archive: string;
indexPattern: { name: string; timeField: string };
dataView: { name: string; timeField: string };
job: DeepPartial<DataFrameAnalyticsConfig>;
sortBy: {
column: string;
@ -38,7 +38,7 @@ export default function ({ getService }: FtrProviderContext) {
{
suiteTitle: 'binary classification job',
archive: 'x-pack/test/functional/es_archives/ml/ihp_outlier',
indexPattern: { name: 'ft_ihp_outlier', timeField: '@timestamp' },
dataView: { name: 'ft_ihp_outlier', timeField: '@timestamp' },
job: {
id: `ihp_fi_binary_${timestamp}`,
description:
@ -107,7 +107,7 @@ export default function ({ getService }: FtrProviderContext) {
{
suiteTitle: 'multi class classification job',
archive: 'x-pack/test/functional/es_archives/ml/ihp_outlier',
indexPattern: { name: 'ft_ihp_outlier', timeField: '@timestamp' },
dataView: { name: 'ft_ihp_outlier', timeField: '@timestamp' },
job: {
id: `ihp_fi_multi_${timestamp}`,
description:
@ -178,7 +178,7 @@ export default function ({ getService }: FtrProviderContext) {
{
suiteTitle: 'regression job',
archive: 'x-pack/test/functional/es_archives/ml/egs_regression',
indexPattern: { name: 'ft_egs_regression', timeField: '@timestamp' },
dataView: { name: 'ft_egs_regression', timeField: '@timestamp' },
job: {
id: `egs_fi_reg_${timestamp}`,
description: 'This is the job description',
@ -253,8 +253,8 @@ export default function ({ getService }: FtrProviderContext) {
for (const testData of testDataList) {
await esArchiver.loadIfNeeded(testData.archive);
await ml.testResources.createDataViewIfNeeded(
testData.indexPattern.name,
testData.indexPattern.timeField
testData.dataView.name,
testData.dataView.timeField
);
await ml.api.createAndRunDFAJob(testData.job as DataFrameAnalyticsConfig);
}
@ -263,7 +263,7 @@ export default function ({ getService }: FtrProviderContext) {
after(async () => {
await ml.api.cleanMlIndices();
for (const testData of testDataList) {
await ml.testResources.deleteDataViewByTitle(testData.indexPattern.name);
await ml.testResources.deleteDataViewByTitle(testData.dataView.name);
}
});

View file

@ -18,7 +18,7 @@ import { MlCustomUrls } from './custom_urls';
export interface DiscoverUrlConfig {
label: string;
indexPattern: string;
indexName: string;
queryEntityFieldNames: string[];
timeRange: TimeRangeType;
timeRangeInterval?: string;
@ -98,7 +98,7 @@ export function MachineLearningDataFrameAnalyticsEditProvider(
);
await mlCommonUI.selectSelectValueByVisibleText(
'mlJobCustomUrlDiscoverIndexPatternInput',
customUrl.indexPattern
customUrl.indexName
);
await customUrls.setCustomUrlQueryEntityFieldNames(customUrl.queryEntityFieldNames);
if (addTimerange) {