Skip to content

Commit

Permalink
[ML] Fixes handling of built-in models (elastic#92154)
Browse files Browse the repository at this point in the history
* [ML] add description column and details tab

* [ML] restrict build-in models actions

* [ML] add description to the details tab

* [ML] add flex with wrap to the type column

* [ML] remove unused code for filtering
  • Loading branch information
darnautov authored and kibanamachine committed Feb 22, 2021
1 parent ee68eff commit 527a35b
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 174 deletions.
2 changes: 2 additions & 0 deletions x-pack/plugins/ml/common/constants/data_frame_analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,6 @@ export const JOB_MAP_NODE_TYPES = {
TRAINED_MODEL: 'trainedModel',
} as const;

export const BUILT_IN_MODEL_TAG = 'prepackaged';

export type JobMapNodeTypes = typeof JOB_MAP_NODE_TYPES[keyof typeof JOB_MAP_NODE_TYPES];
3 changes: 2 additions & 1 deletion x-pack/plugins/ml/common/types/trained_models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export interface TrainedModelStat {
}

export interface TrainedModelConfigResponse {
description: string;
created_by: string;
create_time: string;
default_field_map: Record<string, string>;
Expand All @@ -61,7 +62,7 @@ export interface TrainedModelConfigResponse {
}
| Record<string, any>;
model_id: string;
tags: string;
tags: string[];
version: string;
inference_config?: Record<string, any>;
pipelines?: Record<string, PipelineDefinition> | null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,68 +12,6 @@ import {
Value,
DataFrameAnalyticsListRow,
} from '../pages/analytics_management/components/analytics_list/common';
import { ModelItem } from '../pages/analytics_management/components/models_management/models_list';

export function filterAnalyticsModels(
items: ModelItem[],
clauses: Array<TermClause | FieldClause>
) {
if (clauses.length === 0) {
return items;
}

// keep count of the number of matches we make as we're looping over the clauses
// we only want to return items which match all clauses, i.e. each search term is ANDed
const matches: Record<string, any> = items.reduce((p: Record<string, any>, c) => {
p[c.model_id] = {
model: c,
count: 0,
};
return p;
}, {});

clauses.forEach((c) => {
// the search term could be negated with a minus, e.g. -bananas
const bool = c.match === 'must';
let ms = [];

if (c.type === 'term') {
// filter term based clauses, e.g. bananas
// match on model_id and type
// if the term has been negated, AND the matches
if (bool === true) {
ms = items.filter(
(item) =>
stringMatch(item.model_id, c.value) === bool || stringMatch(item.type, c.value) === bool
);
} else {
ms = items.filter(
(item) =>
stringMatch(item.model_id, c.value) === bool && stringMatch(item.type, c.value) === bool
);
}
} else {
// filter other clauses, i.e. the filters for type
if (Array.isArray(c.value)) {
// type value is an array of string(s) e.g. c.value => ['classification']
ms = items.filter((item) => {
return item.type !== undefined && (c.value as Value[]).includes(item.type);
});
} else {
ms = items.filter((item) => item[c.field as keyof typeof item] === c.value);
}
}

ms.forEach((j) => matches[j.model_id].count++);
});

// loop through the matches and return only those items which have match all the clauses
const filtered = Object.values(matches)
.filter((m) => (m && m.count) >= clauses.length)
.map((m) => m.model);

return filtered;
}

export function filterAnalytics(
items: DataFrameAnalyticsListRow[],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,11 @@ export const ExpandedRow: FC<ExpandedRowProps> = ({ item }) => {
// eslint-disable-next-line @typescript-eslint/naming-convention
license_level,
pipelines,
description,
} = item;

const details = {
description,
tags,
version,
estimated_operations,
Expand Down Expand Up @@ -104,8 +106,8 @@ export const ExpandedRow: FC<ExpandedRowProps> = ({ item }) => {
),
};
})
.filter(({ description }) => {
return description !== undefined;
.filter(({ description: d }) => {
return d !== undefined;
});
}

Expand Down Expand Up @@ -365,62 +367,64 @@ export const ExpandedRow: FC<ExpandedRowProps> = ({ item }) => {
<>
<EuiSpacer size={'m'} />
<EuiFlexGrid columns={2} gutterSize={'m'}>
{Object.entries(pipelines).map(([pipelineName, { processors, description }]) => {
return (
<EuiFlexItem key={pipelineName}>
<EuiPanel>
<EuiFlexGroup alignItems="center" justifyContent="spaceBetween">
<EuiFlexItem grow={false}>
<EuiTitle size={'xs'}>
<h5>{pipelineName}</h5>
</EuiTitle>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButtonEmpty
onClick={async () => {
const ingestPipelinesAppUrlGenerator = share.urlGenerators.getUrlGenerator(
'INGEST_PIPELINES_APP_URL_GENERATOR'
);
await navigateToUrl(
await ingestPipelinesAppUrlGenerator.createUrl({
page: 'pipeline_edit',
pipelineId: pipelineName,
absolute: true,
})
);
}}
>
{Object.entries(pipelines).map(
([pipelineName, { processors, description: pipelineDescription }]) => {
return (
<EuiFlexItem key={pipelineName}>
<EuiPanel>
<EuiFlexGroup alignItems="center" justifyContent="spaceBetween">
<EuiFlexItem grow={false}>
<EuiTitle size={'xs'}>
<h5>{pipelineName}</h5>
</EuiTitle>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButtonEmpty
onClick={async () => {
const ingestPipelinesAppUrlGenerator = share.urlGenerators.getUrlGenerator(
'INGEST_PIPELINES_APP_URL_GENERATOR'
);
await navigateToUrl(
await ingestPipelinesAppUrlGenerator.createUrl({
page: 'pipeline_edit',
pipelineId: pipelineName,
absolute: true,
})
);
}}
>
<FormattedMessage
id="xpack.ml.trainedModels.modelsList.expandedRow.editPipelineLabel"
defaultMessage="Edit"
/>
</EuiButtonEmpty>
</EuiFlexItem>
</EuiFlexGroup>

{pipelineDescription && <EuiText>{pipelineDescription}</EuiText>}
<EuiSpacer size={'m'} />
<EuiTitle size={'xxs'}>
<h6>
<FormattedMessage
id="xpack.ml.trainedModels.modelsList.expandedRow.editPipelineLabel"
defaultMessage="Edit"
id="xpack.ml.trainedModels.modelsList.expandedRow.processorsTitle"
defaultMessage="Processors"
/>
</EuiButtonEmpty>
</EuiFlexItem>
</EuiFlexGroup>

{description && <EuiText>{description}</EuiText>}
<EuiSpacer size={'m'} />
<EuiTitle size={'xxs'}>
<h6>
<FormattedMessage
id="xpack.ml.trainedModels.modelsList.expandedRow.processorsTitle"
defaultMessage="Processors"
/>
</h6>
</EuiTitle>
<EuiCodeBlock
language="painless"
fontSize="m"
paddingSize="m"
overflowHeight={300}
isCopyable
>
{JSON.stringify(processors, null, 2)}
</EuiCodeBlock>
</EuiPanel>
</EuiFlexItem>
);
})}
</h6>
</EuiTitle>
<EuiCodeBlock
language="painless"
fontSize="m"
paddingSize="m"
overflowHeight={300}
isCopyable
>
{JSON.stringify(processors, null, 2)}
</EuiCodeBlock>
</EuiPanel>
</EuiFlexItem>
);
}
)}
</EuiFlexGrid>
</>
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export * from './models_list';

export const ModelsTableToConfigMapping = {
id: 'model_id',
description: 'description',
createdAt: 'create_time',
type: 'type',
} as const;
Loading

0 comments on commit 527a35b

Please sign in to comment.