mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[8.10][ESRE] Parse multiple fields when attaching (#161295)
## Summary This PR adds support for parsing multiple field mappings from an existing pipeline configuration. This is only relevant when listing attachable pipelines; the new pipeline creation process is not affected. This change is a pre-requisite for allowing ELSER pipelines to be attached. Tested for backward compatibility: * Existing pipeline selection dropdown (temporarily disabled filtering of ELSER pipelines)  Note the "Source field" and "Destination field" attributes show the first mapping's fields only (even if the pipeline is configured with multiple mappings). This is pending redesign and will be addressed in a later PR. * Fields - ELSER pipeline (temporarily removed field modification widgets)  * Fields - non-ELSER pipeline  ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios
This commit is contained in:
parent
7709670d92
commit
060cc5b029
4 changed files with 80 additions and 18 deletions
|
@ -381,12 +381,59 @@ describe('parseMlInferenceParametersFromPipeline', () => {
|
|||
model_id: 'test-model',
|
||||
pipeline_name: 'unit-test',
|
||||
source_field: 'body',
|
||||
field_mappings: [
|
||||
{
|
||||
sourceField: 'body',
|
||||
targetField: 'ml.inference.test',
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
it('return null if pipeline missing inference processor', () => {
|
||||
it('returns pipeline parameters from ingest pipeline with multiple inference processors', () => {
|
||||
expect(
|
||||
parseMlInferenceParametersFromPipeline('unit-test', {
|
||||
processors: [
|
||||
{
|
||||
inference: {
|
||||
field_map: {
|
||||
body: 'text_field',
|
||||
},
|
||||
model_id: 'test-model',
|
||||
target_field: 'ml.inference.body',
|
||||
},
|
||||
},
|
||||
{
|
||||
inference: {
|
||||
field_map: {
|
||||
title: 'text_field',
|
||||
},
|
||||
model_id: 'test-model',
|
||||
target_field: 'ml.inference.title',
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
).toEqual({
|
||||
destination_field: 'body',
|
||||
model_id: 'test-model',
|
||||
pipeline_name: 'unit-test',
|
||||
source_field: 'body',
|
||||
field_mappings: [
|
||||
{
|
||||
sourceField: 'body',
|
||||
targetField: 'ml.inference.body',
|
||||
},
|
||||
{
|
||||
sourceField: 'title',
|
||||
targetField: 'ml.inference.title',
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
it('return null if pipeline is missing inference processor', () => {
|
||||
expect(parseMlInferenceParametersFromPipeline('unit-test', { processors: [] })).toBeNull();
|
||||
});
|
||||
it('return null if pipeline missing field_map', () => {
|
||||
it('return null if pipeline is missing field_map', () => {
|
||||
expect(
|
||||
parseMlInferenceParametersFromPipeline('unit-test', {
|
||||
processors: [
|
||||
|
|
|
@ -216,24 +216,37 @@ export const parseMlInferenceParametersFromPipeline = (
|
|||
name: string,
|
||||
pipeline: IngestPipeline
|
||||
): CreateMlInferencePipelineParameters | null => {
|
||||
const processor = pipeline?.processors?.find((proc) => proc.inference !== undefined);
|
||||
if (!processor || processor?.inference === undefined) {
|
||||
const inferenceProcessors = pipeline?.processors
|
||||
?.filter((p) => p.inference)
|
||||
.map((p) => p.inference) as IngestInferenceProcessor[];
|
||||
if (!inferenceProcessors || inferenceProcessors.length === 0) {
|
||||
return null;
|
||||
}
|
||||
const { inference: inferenceProcessor } = processor;
|
||||
const sourceFields = Object.keys(inferenceProcessor.field_map ?? {});
|
||||
const sourceField = sourceFields.length === 1 ? sourceFields[0] : null;
|
||||
if (!sourceField) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
destination_field: inferenceProcessor.target_field
|
||||
? stripMlInferencePrefix(inferenceProcessor.target_field)
|
||||
: inferenceProcessor.target_field,
|
||||
model_id: inferenceProcessor.model_id,
|
||||
pipeline_name: name,
|
||||
source_field: sourceField,
|
||||
};
|
||||
|
||||
// Extract source -> target field mappings from all inference processors in pipeline
|
||||
const fieldMappings = inferenceProcessors
|
||||
.map((p) => {
|
||||
const sourceFields = Object.keys(p.field_map ?? {});
|
||||
// We assume that there is only one source field per inference processor
|
||||
const sourceField = sourceFields.length >= 1 ? sourceFields[0] : null;
|
||||
return {
|
||||
sourceField,
|
||||
targetField: p.target_field, // Prefixed target field
|
||||
};
|
||||
})
|
||||
.filter((f) => f.sourceField) as FieldMapping[];
|
||||
|
||||
return fieldMappings.length === 0
|
||||
? null
|
||||
: {
|
||||
destination_field: fieldMappings[0].targetField // Backward compatibility - TODO: remove after multi-field selector is implemented for all inference types
|
||||
? stripMlInferencePrefix(fieldMappings[0].targetField)
|
||||
: '',
|
||||
model_id: inferenceProcessors[0].model_id,
|
||||
pipeline_name: name,
|
||||
source_field: fieldMappings[0].sourceField, // Backward compatibility - TODO: remove after multi-field selector is implemented for all inference types
|
||||
field_mappings: fieldMappings,
|
||||
};
|
||||
};
|
||||
|
||||
export const parseModelStateFromStats = (
|
||||
|
|
|
@ -80,6 +80,7 @@ export interface CreateMlInferencePipelineParameters {
|
|||
model_id: string;
|
||||
pipeline_name: string;
|
||||
source_field: string;
|
||||
field_mappings?: FieldMapping[];
|
||||
}
|
||||
|
||||
export interface CreateMLInferencePipelineDefinition {
|
||||
|
|
|
@ -326,6 +326,7 @@ export const MLInferenceLogic = kea<
|
|||
modelID: params.model_id,
|
||||
pipelineName,
|
||||
sourceField: params.source_field,
|
||||
fieldMappings: params.field_mappings,
|
||||
});
|
||||
},
|
||||
setIndexName: ({ indexName }) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue