mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[8.11] [ML] AIOps: Fix Data View runtime fields support in Change point detection UI (#168249) (#168491)
# Backport This will backport the following commits from `main` to `8.11`: - [[ML] AIOps: Fix Data View runtime fields support in Change point detection UI (#168249)](https://github.com/elastic/kibana/pull/168249) <!--- Backport version: 8.9.7 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Dima Arnautov","email":"dmitrii.arnautov@elastic.co"},"sourceCommit":{"committedDate":"2023-10-10T14:55:03Z","message":"[ML] AIOps: Fix Data View runtime fields support in Change point detection UI (#168249)\n\n## Summary\r\n\r\nFixes [#162212](https://github.com/elastic/kibana/issues/168212)\r\n\r\nIf a Data View runtime field is used as a metric or split field, appends\r\na `runtime_mappings` to the search request.\r\n\r\n### Checklist\r\n\r\n- [ ] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios","sha":"9f06e30a4e9addf1db6a3e78a11103d644e37995","branchLabelMapping":{"^v8.12.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix",":ml","Team:ML","Feature:ML/AIOps","v8.11.0","v8.12.0"],"number":168249,"url":"https://github.com/elastic/kibana/pull/168249","mergeCommit":{"message":"[ML] AIOps: Fix Data View runtime fields support in Change point detection UI (#168249)\n\n## Summary\r\n\r\nFixes [#162212](https://github.com/elastic/kibana/issues/168212)\r\n\r\nIf a Data View runtime field is used as a metric or split field, appends\r\na `runtime_mappings` to the search request.\r\n\r\n### Checklist\r\n\r\n- [ ] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios","sha":"9f06e30a4e9addf1db6a3e78a11103d644e37995"}},"sourceBranch":"main","suggestedTargetBranches":["8.11"],"targetPullRequestStates":[{"branch":"8.11","label":"v8.11.0","labelRegex":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.12.0","labelRegex":"^v8.12.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/168249","number":168249,"mergeCommit":{"message":"[ML] AIOps: Fix Data View runtime fields support in Change point detection UI (#168249)\n\n## Summary\r\n\r\nFixes [#162212](https://github.com/elastic/kibana/issues/168212)\r\n\r\nIf a Data View runtime field is used as a metric or split field, appends\r\na `runtime_mappings` to the search request.\r\n\r\n### Checklist\r\n\r\n- [ ] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios","sha":"9f06e30a4e9addf1db6a3e78a11103d644e37995"}}]}] BACKPORT--> Co-authored-by: Dima Arnautov <dmitrii.arnautov@elastic.co>
This commit is contained in:
parent
636a8339cf
commit
fc9892165d
3 changed files with 81 additions and 44 deletions
|
@ -9,12 +9,17 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
|
|||
import { type QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { isDefined } from '@kbn/ml-is-defined';
|
||||
import type {
|
||||
MappingRuntimeFields,
|
||||
SearchRequest,
|
||||
} from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import { useReload } from '../../hooks/use_reload';
|
||||
import { useAiopsAppContext } from '../../hooks/use_aiops_app_context';
|
||||
import {
|
||||
ChangePointAnnotation,
|
||||
ChangePointDetectionRequestParams,
|
||||
FieldConfig,
|
||||
useChangePointDetectionControlsContext,
|
||||
} from './change_point_detection_context';
|
||||
import { useDataSource } from '../../hooks/use_data_source';
|
||||
import { useCancellableSearch } from '../../hooks/use_cancellable_search';
|
||||
|
@ -37,8 +42,9 @@ interface RequestOptions {
|
|||
|
||||
function getChangePointDetectionRequestBody(
|
||||
{ index, fn, metricField, splitField, timeInterval, timeField, afterKey }: RequestOptions,
|
||||
query: QueryDslQueryContainer
|
||||
) {
|
||||
query: QueryDslQueryContainer,
|
||||
runtimeMappings: MappingRuntimeFields
|
||||
): SearchRequest {
|
||||
const timeSeriesAgg = {
|
||||
over_time: {
|
||||
date_histogram: {
|
||||
|
@ -98,15 +104,14 @@ function getChangePointDetectionRequestBody(
|
|||
: timeSeriesAgg;
|
||||
|
||||
return {
|
||||
params: {
|
||||
index,
|
||||
size: 0,
|
||||
body: {
|
||||
...(query ? { query } : {}),
|
||||
aggregations,
|
||||
},
|
||||
index,
|
||||
size: 0,
|
||||
body: {
|
||||
...(query ? { query } : {}),
|
||||
...(runtimeMappings ? { runtime_mappings: runtimeMappings } : {}),
|
||||
aggregations,
|
||||
},
|
||||
};
|
||||
} as SearchRequest;
|
||||
}
|
||||
|
||||
export function useChangePointResults(
|
||||
|
@ -120,7 +125,7 @@ export function useChangePointResults(
|
|||
} = useAiopsAppContext();
|
||||
|
||||
const { dataView } = useDataSource();
|
||||
|
||||
const { splitFieldsOptions, metricFieldOptions } = useChangePointDetectionControlsContext();
|
||||
const { refreshTimestamp: refresh } = useReload();
|
||||
|
||||
const [results, setResults] = useState<ChangePointAnnotation[]>([]);
|
||||
|
@ -152,7 +157,23 @@ export function useChangePointResults(
|
|||
return;
|
||||
}
|
||||
|
||||
const requestPayload = getChangePointDetectionRequestBody(
|
||||
const metricFieldDV = metricFieldOptions.find(
|
||||
(option) => option.name === fieldConfig.metricField
|
||||
);
|
||||
const splitFieldDV = splitFieldsOptions.find(
|
||||
(option) => option.name === fieldConfig.splitField
|
||||
);
|
||||
|
||||
const runtimeMappings = {
|
||||
...(metricFieldDV?.isRuntimeField
|
||||
? { [metricFieldDV.name]: metricFieldDV.runtimeField! }
|
||||
: {}),
|
||||
...(splitFieldDV?.isRuntimeField
|
||||
? { [splitFieldDV.name]: splitFieldDV.runtimeField! }
|
||||
: {}),
|
||||
} as MappingRuntimeFields;
|
||||
|
||||
const requestPayload: SearchRequest = getChangePointDetectionRequestBody(
|
||||
{
|
||||
index: dataView.getIndexPattern(),
|
||||
fn: fieldConfig.fn,
|
||||
|
@ -162,13 +183,14 @@ export function useChangePointResults(
|
|||
splitField: fieldConfig.splitField,
|
||||
afterKey,
|
||||
},
|
||||
query
|
||||
query,
|
||||
runtimeMappings
|
||||
);
|
||||
|
||||
const result = await runRequest<
|
||||
typeof requestPayload,
|
||||
{ params: SearchRequest },
|
||||
{ rawResponse: ChangePointAggResponse }
|
||||
>(requestPayload);
|
||||
>({ params: requestPayload });
|
||||
|
||||
if (result === null) {
|
||||
setProgress(null);
|
||||
|
@ -176,7 +198,7 @@ export function useChangePointResults(
|
|||
}
|
||||
|
||||
const isFetchCompleted = !(
|
||||
result.rawResponse.aggregations?.groupings?.after_key?.splitFieldTerm &&
|
||||
isDefined(result.rawResponse.aggregations?.groupings?.after_key?.splitFieldTerm) &&
|
||||
pageNumber < totalAggPages
|
||||
);
|
||||
|
||||
|
@ -227,11 +249,11 @@ export function useChangePointResults(
|
|||
|
||||
if (
|
||||
!isFetchCompleted &&
|
||||
result.rawResponse.aggregations?.groupings?.after_key?.splitFieldTerm
|
||||
isDefined(result.rawResponse.aggregations?.groupings?.after_key?.splitFieldTerm)
|
||||
) {
|
||||
await fetchResults(
|
||||
pageNumber + 1,
|
||||
result.rawResponse.aggregations.groupings.after_key.splitFieldTerm
|
||||
result.rawResponse.aggregations.groupings.after_key!.splitFieldTerm
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
|
@ -243,17 +265,19 @@ export function useChangePointResults(
|
|||
}
|
||||
},
|
||||
[
|
||||
runRequest,
|
||||
requestParams.interval,
|
||||
requestParams.changePointType,
|
||||
isSingleMetric,
|
||||
totalAggPages,
|
||||
dataView,
|
||||
fieldConfig.fn,
|
||||
fieldConfig.metricField,
|
||||
fieldConfig.splitField,
|
||||
requestParams.interval,
|
||||
requestParams.changePointType,
|
||||
query,
|
||||
dataView,
|
||||
totalAggPages,
|
||||
metricFieldOptions,
|
||||
splitFieldsOptions,
|
||||
runRequest,
|
||||
toasts,
|
||||
isSingleMetric,
|
||||
]
|
||||
);
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import type {
|
|||
SearchResponseBody,
|
||||
} from '@elastic/elasticsearch/lib/api/types';
|
||||
import usePrevious from 'react-use/lib/usePrevious';
|
||||
import { useChangePointDetectionControlsContext } from './change_point_detection_context';
|
||||
import { useCancellableSearch } from '../../hooks/use_cancellable_search';
|
||||
import { useDataSource } from '../../hooks/use_data_source';
|
||||
|
||||
|
@ -25,11 +26,19 @@ export function useSplitFieldCardinality(
|
|||
query: QueryDslQueryContainer
|
||||
) {
|
||||
const prevSplitField = usePrevious(splitField);
|
||||
const { splitFieldsOptions } = useChangePointDetectionControlsContext();
|
||||
|
||||
const [cardinality, setCardinality] = useState<number | null>(null);
|
||||
const { dataView } = useDataSource();
|
||||
|
||||
const requestPayload = useMemo(() => {
|
||||
const optionDefinition = splitFieldsOptions.find((option) => option.name === splitField);
|
||||
let runtimeMappings = {};
|
||||
if (optionDefinition?.isRuntimeField) {
|
||||
runtimeMappings = {
|
||||
runtime_mappings: { [optionDefinition.name]: optionDefinition.runtimeField },
|
||||
};
|
||||
}
|
||||
return {
|
||||
params: {
|
||||
index: dataView.getIndexPattern(),
|
||||
|
@ -43,10 +52,11 @@ export function useSplitFieldCardinality(
|
|||
},
|
||||
},
|
||||
},
|
||||
...runtimeMappings,
|
||||
},
|
||||
},
|
||||
};
|
||||
}, [splitField, dataView, query]);
|
||||
}, [splitField, dataView, query, splitFieldsOptions]);
|
||||
|
||||
const { runRequest: getSplitFieldCardinality, cancelRequest } = useCancellableSearch();
|
||||
|
||||
|
|
|
@ -12,9 +12,10 @@ import { useTimefilter } from '@kbn/ml-date-picker';
|
|||
import { css } from '@emotion/react';
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
import { ReloadContextProvider } from '../hooks/use_reload';
|
||||
import type {
|
||||
ChangePointAnnotation,
|
||||
ChangePointDetectionRequestParams,
|
||||
import {
|
||||
type ChangePointAnnotation,
|
||||
ChangePointDetectionControlsContextProvider,
|
||||
type ChangePointDetectionRequestParams,
|
||||
} from '../components/change_point_detection/change_point_detection_context';
|
||||
import type {
|
||||
EmbeddableChangePointChartInput,
|
||||
|
@ -82,22 +83,24 @@ export const EmbeddableInputTracker: FC<EmbeddableInputTrackerProps> = ({
|
|||
return (
|
||||
<ReloadContextProvider reload$={resultObservable$}>
|
||||
<DataSourceContextProvider dataViewId={input.dataViewId}>
|
||||
<FilterQueryContextProvider timeRange={input.timeRange}>
|
||||
<ChartGridEmbeddableWrapper
|
||||
timeRange={input.timeRange}
|
||||
fn={input.fn}
|
||||
metricField={input.metricField}
|
||||
splitField={input.splitField}
|
||||
maxSeriesToPlot={input.maxSeriesToPlot}
|
||||
dataViewId={input.dataViewId}
|
||||
partitions={input.partitions}
|
||||
onLoading={onLoading}
|
||||
onRenderComplete={onRenderComplete}
|
||||
onError={onError}
|
||||
onChange={input.onChange}
|
||||
emptyState={input.emptyState}
|
||||
/>
|
||||
</FilterQueryContextProvider>
|
||||
<ChangePointDetectionControlsContextProvider>
|
||||
<FilterQueryContextProvider timeRange={input.timeRange}>
|
||||
<ChartGridEmbeddableWrapper
|
||||
timeRange={input.timeRange}
|
||||
fn={input.fn}
|
||||
metricField={input.metricField}
|
||||
splitField={input.splitField}
|
||||
maxSeriesToPlot={input.maxSeriesToPlot}
|
||||
dataViewId={input.dataViewId}
|
||||
partitions={input.partitions}
|
||||
onLoading={onLoading}
|
||||
onRenderComplete={onRenderComplete}
|
||||
onError={onError}
|
||||
onChange={input.onChange}
|
||||
emptyState={input.emptyState}
|
||||
/>
|
||||
</FilterQueryContextProvider>
|
||||
</ChangePointDetectionControlsContextProvider>
|
||||
</DataSourceContextProvider>
|
||||
</ReloadContextProvider>
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue