Skip to content

Commit d47ccd5

Browse files
qn895kibanamachine
authored andcommitted
[ML] Fix Anomaly Detection wizard full time range chart blank with saved search containing runtime fields (#95700)
* [ML] Fix AD wizard full time range chart broken with saved search * [ML] Update runtimeMappingsSchema to be its own thing for better reuse * [ML] Remove undefined check
1 parent 2c5a9a7 commit d47ccd5

13 files changed

Lines changed: 52 additions & 24 deletions

File tree

x-pack/plugins/ml/common/util/runtime_field_utils.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@
66
*/
77

88
import { isPopulatedObject } from './object_utils';
9-
import {
10-
RUNTIME_FIELD_TYPES,
11-
RuntimeType,
12-
} from '../../../../../src/plugins/data/common/index_patterns';
9+
import { RUNTIME_FIELD_TYPES } from '../../../../../src/plugins/data/common/index_patterns';
1310
import type { RuntimeField, RuntimeMappings } from '../types/fields';
1411

1512
export function isRuntimeField(arg: unknown): arg is RuntimeField {
@@ -24,7 +21,7 @@ export function isRuntimeField(arg: unknown): arg is RuntimeField {
2421
Object.keys(arg.script).length === 1 &&
2522
arg.script.hasOwnProperty('source') &&
2623
typeof arg.script.source === 'string')))) &&
27-
RUNTIME_FIELD_TYPES.includes(arg.type as RuntimeType)
24+
RUNTIME_FIELD_TYPES.includes(arg.type)
2825
);
2926
}
3027

x-pack/plugins/ml/public/application/components/model_snapshots/revert_model_snapshot_flyout/chart_loader.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export function chartLoaderProvider(mlResultsService: MlResultsService) {
3030
job.data_counts.earliest_record_timestamp,
3131
job.data_counts.latest_record_timestamp,
3232
intervalMs,
33+
job.datafeed_config.runtime_mappings,
3334
// @ts-expect-error @elastic/elasticsearch Datafeed is missing indices_options
3435
job.datafeed_config.indices_options
3536
);

x-pack/plugins/ml/public/application/jobs/new_job/common/chart_loader/chart_loader.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ export class ChartLoader {
128128
start: number,
129129
end: number,
130130
intervalMs: number,
131+
runtimeMappings?: RuntimeMappings,
131132
indicesOptions?: IndicesOptions
132133
): Promise<LineChartPoint[]> {
133134
if (this._timeFieldName !== '') {
@@ -138,6 +139,7 @@ export class ChartLoader {
138139
start,
139140
end,
140141
intervalMs * 3,
142+
runtimeMappings,
141143
indicesOptions
142144
);
143145
if (resp.error !== undefined) {

x-pack/plugins/ml/public/application/jobs/new_job/pages/components/pick_fields_step/components/categorization_view/metric_selection_summary.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export const CategorizationDetectorsSummary: FC = () => {
5555
jobCreator.start,
5656
jobCreator.end,
5757
chartInterval.getInterval().asMilliseconds(),
58+
jobCreator.runtimeMappings ?? undefined,
5859
// @ts-expect-error @elastic/elasticsearch Datafeed is missing indices_options
5960
jobCreator.datafeedConfig.indices_options
6061
);

x-pack/plugins/ml/public/application/jobs/new_job/pages/components/time_range_step/time_range.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export const TimeRangeStep: FC<StepProps> = ({ setCurrentStep, isCurrentStep })
4848
jobCreator.start,
4949
jobCreator.end,
5050
chartInterval.getInterval().asMilliseconds(),
51+
jobCreator.runtimeMappings ?? undefined,
5152
// @ts-expect-error @elastic/elasticsearch Datafeed is missing indices_options
5253
jobCreator.datafeedConfig.indices_options
5354
);

x-pack/plugins/ml/public/application/jobs/new_job/recognize/page.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ import { JobId } from '../../../../../common/types/anomaly_detection_jobs';
4444
import { ML_PAGES } from '../../../../../common/constants/ml_url_generator';
4545
import { TIME_FORMAT } from '../../../../../common/constants/time_format';
4646
import { JobsAwaitingNodeWarning } from '../../../components/jobs_awaiting_node_warning';
47+
import { isPopulatedObject } from '../../../../../common/util/object_utils';
48+
import { RuntimeMappings } from '../../../../../common/types/fields';
4749

4850
export interface ModuleJobUI extends ModuleJob {
4951
datafeedResult?: DatafeedResponse;
@@ -133,10 +135,12 @@ export const Page: FC<PageProps> = ({ moduleId, existingGroupIds }) => {
133135
timeRange: TimeRange
134136
): Promise<TimeRange> => {
135137
if (useFullIndexData) {
138+
const runtimeMappings = indexPattern.getComputedFields().runtimeFields as RuntimeMappings;
136139
const { start, end } = await ml.getTimeFieldRange({
137140
index: indexPattern.title,
138141
timeFieldName: indexPattern.timeFieldName,
139142
query: combinedQuery,
143+
...(isPopulatedObject(runtimeMappings) ? { runtimeMappings } : {}),
140144
});
141145
return {
142146
start: start.epoch,

x-pack/plugins/ml/public/application/services/results_service/results_service.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { MlApiServices } from '../ml_api_service';
1010
import type { AnomalyRecordDoc } from '../../../../common/types/anomalies';
1111
import { InfluencersFilterQuery } from '../../../../common/types/es_client';
1212
import { EntityField } from '../../../../common/util/anomaly_utils';
13+
import { RuntimeMappings } from '../../../../common/types/fields';
1314

1415
type RecordForInfluencer = AnomalyRecordDoc;
1516
export function resultsServiceProvider(
@@ -64,6 +65,7 @@ export function resultsServiceProvider(
6465
earliestMs: number,
6566
latestMs: number,
6667
intervalMs: number,
68+
runtimeMappings?: RuntimeMappings,
6769
indicesOptions?: IndicesOptions
6870
): Promise<any>;
6971
getEventDistributionData(

x-pack/plugins/ml/public/application/services/results_service/results_service.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
SWIM_LANE_DEFAULT_PAGE_SIZE,
1515
} from '../../explorer/explorer_constants';
1616
import { aggregationTypeTransform } from '../../../../common/util/anomaly_utils';
17+
import { isPopulatedObject } from '../../../../common/util/object_utils';
1718

1819
/**
1920
* Service for carrying out Elasticsearch queries to obtain data for the Ml Results dashboards.
@@ -1059,6 +1060,7 @@ export function resultsServiceProvider(mlApiServices) {
10591060
earliestMs,
10601061
latestMs,
10611062
intervalMs,
1063+
runtimeMappings,
10621064
indicesOptions
10631065
) {
10641066
return new Promise((resolve, reject) => {
@@ -1109,6 +1111,12 @@ export function resultsServiceProvider(mlApiServices) {
11091111
},
11101112
},
11111113
},
1114+
// Runtime mappings only needed to support when query includes a runtime field
1115+
// even though the default timeField can be a search time runtime field
1116+
// because currently Kibana doesn't support that
1117+
...(isPopulatedObject(runtimeMappings) && query
1118+
? { runtime_mappings: runtimeMappings }
1119+
: {}),
11121120
},
11131121
...(indicesOptions ?? {}),
11141122
})

x-pack/plugins/ml/server/routes/schemas/data_visualizer_schema.ts

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,13 @@
66
*/
77

88
import { schema } from '@kbn/config-schema';
9-
import { isRuntimeField } from '../../../common/util/runtime_field_utils';
9+
import { runtimeMappingsSchema } from './runtime_mappings_schema';
1010

1111
export const indexPatternTitleSchema = schema.object({
1212
/** Title of the index pattern for which to return stats. */
1313
indexPatternTitle: schema.string(),
1414
});
1515

16-
const runtimeMappingsSchema = schema.maybe(
17-
schema.object(
18-
{},
19-
{
20-
unknowns: 'allow',
21-
validate: (v: object) => {
22-
if (Object.values(v).some((o) => !isRuntimeField(o))) {
23-
return 'Invalid runtime field';
24-
}
25-
},
26-
}
27-
)
28-
);
29-
3016
export const dataVisualizerFieldHistogramsSchema = schema.object({
3117
/** Query to match documents in the index. */
3218
query: schema.any(),

x-pack/plugins/ml/server/routes/schemas/fields_service_schema.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import { schema } from '@kbn/config-schema';
99
import { indicesOptionsSchema } from './datafeeds_schema';
10+
import { runtimeMappingsSchema } from './runtime_mappings_schema';
1011

1112
export const getCardinalityOfFieldsSchema = schema.object({
1213
/** Index or indexes for which to return the time range. */
@@ -31,6 +32,6 @@ export const getTimeFieldRangeSchema = schema.object({
3132
/** Query to match documents in the index(es). */
3233
query: schema.maybe(schema.any()),
3334
/** Additional search options. */
34-
runtimeMappings: schema.maybe(schema.any()),
35+
runtimeMappings: runtimeMappingsSchema,
3536
indicesOptions: indicesOptionsSchema,
3637
});

0 commit comments

Comments
 (0)