[ML] Fix Anomaly Explorer & Single Metric Viewer not plotting correctly for detectors with non zero count function (#87903)

This commit is contained in:
Quynh Nguyen 2021-01-13 12:19:01 -06:00 committed by GitHub
parent badd2b35f2
commit 6e3a06b4aa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 35 additions and 6 deletions

View file

@ -47,6 +47,7 @@ Object {
"jobId": "mock-job-id", "jobId": "mock-job-id",
"metricFieldName": "responsetime", "metricFieldName": "responsetime",
"metricFunction": "avg", "metricFunction": "avg",
"summaryCountFieldName": undefined,
"timeField": "@timestamp", "timeField": "@timestamp",
} }
`; `;

View file

@ -53,6 +53,7 @@ Object {
"loading": true, "loading": true,
"metricFieldName": "responsetime", "metricFieldName": "responsetime",
"metricFunction": "avg", "metricFunction": "avg",
"summaryCountFieldName": undefined,
"timeField": "@timestamp", "timeField": "@timestamp",
}, },
], ],
@ -600,6 +601,7 @@ Object {
"plotLatest": 1486783800000, "plotLatest": 1486783800000,
"selectedEarliest": 1486656000000, "selectedEarliest": 1486656000000,
"selectedLatest": 1486670399999, "selectedLatest": 1486670399999,
"summaryCountFieldName": undefined,
"timeField": "@timestamp", "timeField": "@timestamp",
}, },
], ],

View file

@ -126,6 +126,7 @@ export const anomalyDataChange = function (
datafeedQuery, datafeedQuery,
config.metricFunction, config.metricFunction,
config.metricFieldName, config.metricFieldName,
config.summaryCountFieldName,
config.timeField, config.timeField,
range.min, range.min,
range.max, range.max,

View file

@ -22,6 +22,7 @@ import { CriteriaField } from './index';
import { findAggField } from '../../../../common/util/validation_utils'; import { findAggField } from '../../../../common/util/validation_utils';
import { getDatafeedAggregations } from '../../../../common/util/datafeed_utils'; import { getDatafeedAggregations } from '../../../../common/util/datafeed_utils';
import { aggregationTypeTransform } from '../../../../common/util/anomaly_utils'; import { aggregationTypeTransform } from '../../../../common/util/anomaly_utils';
import { ES_AGGREGATION } from '../../../../common/constants/aggregation_types';
interface ResultResponse { interface ResultResponse {
success: boolean; success: boolean;
@ -68,6 +69,7 @@ export function resultsServiceRxProvider(mlApiServices: MlApiServices) {
query: object | undefined, query: object | undefined,
metricFunction: string, // ES aggregation name metricFunction: string, // ES aggregation name
metricFieldName: string, metricFieldName: string,
summaryCountFieldName: string | undefined,
timeFieldName: string, timeFieldName: string,
earliestMs: number, earliestMs: number,
latestMs: number, latestMs: number,
@ -153,9 +155,8 @@ export function resultsServiceRxProvider(mlApiServices: MlApiServices) {
body.query.bool.minimum_should_match = shouldCriteria.length / 2; body.query.bool.minimum_should_match = shouldCriteria.length / 2;
} }
body.aggs.byTime.aggs = {};
if (metricFieldName !== undefined && metricFieldName !== '') { if (metricFieldName !== undefined && metricFieldName !== '') {
body.aggs.byTime.aggs = {};
const metricAgg: any = { const metricAgg: any = {
[metricFunction]: {}, [metricFunction]: {},
}; };
@ -186,8 +187,23 @@ export function resultsServiceRxProvider(mlApiServices: MlApiServices) {
} else { } else {
body.aggs.byTime.aggs.metric = metricAgg; body.aggs.byTime.aggs.metric = metricAgg;
} }
} else {
// if metricFieldName is not defined, it's probably a variation of the non zero count function
// refer to buildConfigFromDetector
if (summaryCountFieldName !== undefined && metricFunction === ES_AGGREGATION.CARDINALITY) {
// if so, check if summaryCountFieldName is an aggregation field
if (typeof aggFields === 'object' && Object.keys(aggFields).length > 0) {
// first item under aggregations can be any name, not necessarily 'buckets'
const accessor = Object.keys(aggFields)[0];
const tempAggs = { ...(aggFields[accessor].aggs ?? aggFields[accessor].aggregations) };
const foundCardinalityField = findAggField(tempAggs, summaryCountFieldName);
if (foundCardinalityField !== undefined) {
tempAggs.metric = foundCardinalityField;
}
body.aggs.byTime.aggs = tempAggs;
}
}
} }
return mlApiServices.esSearch$({ index, body }).pipe( return mlApiServices.esSearch$({ index, body }).pipe(
map((resp: any) => { map((resp: any) => {
const obj: MetricData = { success: true, results: {} }; const obj: MetricData = { success: true, results: {} };

View file

@ -91,6 +91,7 @@ function getMetricData(
chartConfig.datafeedConfig.query, chartConfig.datafeedConfig.query,
esMetricFunction ?? chartConfig.metricFunction, esMetricFunction ?? chartConfig.metricFunction,
chartConfig.metricFieldName, chartConfig.metricFieldName,
chartConfig.summaryCountFieldName,
chartConfig.timeField, chartConfig.timeField,
earliestMs, earliestMs,
latestMs, latestMs,

View file

@ -28,6 +28,7 @@ export function buildConfigFromDetector(job, detectorIndex) {
timeField: job.data_description.time_field, timeField: job.data_description.time_field,
interval: job.analysis_config.bucket_span, interval: job.analysis_config.bucket_span,
datafeedConfig: job.datafeed_config, datafeedConfig: job.datafeed_config,
summaryCountFieldName: job.analysis_config.summary_count_field_name,
}; };
if (detector.field_name !== undefined) { if (detector.field_name !== undefined) {
@ -63,10 +64,17 @@ export function buildConfigFromDetector(job, detectorIndex) {
'field', 'field',
]); ]);
} }
if (
if (detector.function === ML_JOB_AGGREGATION.NON_ZERO_COUNT && cardinalityField !== undefined) { (detector.function === ML_JOB_AGGREGATION.NON_ZERO_COUNT ||
detector.function === ML_JOB_AGGREGATION.LOW_NON_ZERO_COUNT ||
detector.function === ML_JOB_AGGREGATION.HIGH_NON_ZERO_COUNT ||
detector.function === ML_JOB_AGGREGATION.COUNT ||
detector.function === ML_JOB_AGGREGATION.HIGH_COUNT ||
detector.function === ML_JOB_AGGREGATION.LOW_COUNT) &&
cardinalityField !== undefined
) {
config.metricFunction = ES_AGGREGATION.CARDINALITY; config.metricFunction = ES_AGGREGATION.CARDINALITY;
config.metricFieldName = cardinalityField; config.metricFieldName = undefined;
} else { } else {
// For count detectors using summary_count_field, plot sum(summary_count_field_name) // For count detectors using summary_count_field, plot sum(summary_count_field_name)
config.metricFunction = ES_AGGREGATION.SUM; config.metricFunction = ES_AGGREGATION.SUM;