Skip to content

Commit

Permalink
[ML] Removing full lodash library imports (elastic#74742)
Browse files Browse the repository at this point in the history
* [ML] Removing full lodash library imports

* more has

* fixing missing filter

* removing _

* removing unused file

* removing first use

* removing comment
  • Loading branch information
jgowdyelastic authored Aug 12, 2020
1 parent 506e953 commit a81059b
Show file tree
Hide file tree
Showing 34 changed files with 365 additions and 371 deletions.
18 changes: 11 additions & 7 deletions x-pack/plugins/ml/common/util/job_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
* you may not use this file except in compliance with the Elastic License.
*/

import _ from 'lodash';
import isEmpty from 'lodash/isEmpty';
import isEqual from 'lodash/isEqual';
import each from 'lodash/each';
import pick from 'lodash/pick';

import semver from 'semver';
import moment, { Duration } from 'moment';
// @ts-ignore
Expand Down Expand Up @@ -307,7 +311,7 @@ export function getSafeAggregationName(fieldName: string, index: number): string

export function uniqWithIsEqual<T extends any[]>(arr: T): T {
return arr.reduce((dedupedArray, value) => {
if (dedupedArray.filter((compareValue: any) => _.isEqual(compareValue, value)).length === 0) {
if (dedupedArray.filter((compareValue: any) => isEqual(compareValue, value)).length === 0) {
dedupedArray.push(value);
}
return dedupedArray;
Expand All @@ -328,7 +332,7 @@ export function basicJobValidation(

if (job) {
// Job details
if (_.isEmpty(job.job_id)) {
if (isEmpty(job.job_id)) {
messages.push({ id: 'job_id_empty' });
valid = false;
} else if (isJobIdValid(job.job_id) === false) {
Expand All @@ -350,7 +354,7 @@ export function basicJobValidation(
// Analysis Configuration
if (job.analysis_config.categorization_filters) {
let v = true;
_.each(job.analysis_config.categorization_filters, (d) => {
each(job.analysis_config.categorization_filters, (d) => {
try {
new RegExp(d);
} catch (e) {
Expand Down Expand Up @@ -382,8 +386,8 @@ export function basicJobValidation(
valid = false;
} else {
let v = true;
_.each(job.analysis_config.detectors, (d) => {
if (_.isEmpty(d.function)) {
each(job.analysis_config.detectors, (d) => {
if (isEmpty(d.function)) {
v = false;
}
});
Expand All @@ -400,7 +404,7 @@ export function basicJobValidation(
// create an array of objects with a subset of the attributes
// where we want to make sure they are not be the same across detectors
const compareSubSet = job.analysis_config.detectors.map((d) =>
_.pick(d, [
pick(d, [
'function',
'field_name',
'by_field_name',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
* This version supports both fetching the annotations by itself (used in the jobs list) and
* getting the annotations via props (used in Anomaly Explorer and Single Series Viewer).
*/
import _ from 'lodash';

import uniq from 'lodash/uniq';

import PropTypes from 'prop-types';
import rison from 'rison-node';
import React, { Component, Fragment } from 'react';
Expand Down Expand Up @@ -255,18 +257,18 @@ export class AnnotationsTable extends Component {

// if the annotation is at the series level
// then pass the partitioning field(s) and detector index to the Single Metric Viewer
if (_.has(annotation, 'detector_index')) {
if (annotation.detector_index !== undefined) {
mlTimeSeriesExplorer.detectorIndex = annotation.detector_index;
}
if (_.has(annotation, 'partition_field_value')) {
if (annotation.partition_field_value !== undefined) {
entityCondition[annotation.partition_field_name] = annotation.partition_field_value;
}

if (_.has(annotation, 'over_field_value')) {
if (annotation.over_field_value !== undefined) {
entityCondition[annotation.over_field_name] = annotation.over_field_value;
}

if (_.has(annotation, 'by_field_value')) {
if (annotation.by_field_value !== undefined) {
// Note that analyses with by and over fields, will have a top-level by_field_name,
// but the by_field_value(s) will be in the nested causes array.
entityCondition[annotation.by_field_name] = annotation.by_field_value;
Expand Down Expand Up @@ -421,7 +423,7 @@ export class AnnotationsTable extends Component {
},
];

const jobIds = _.uniq(annotations.map((a) => a.job_id));
const jobIds = uniq(annotations.map((a) => a.job_id));
if (jobIds.length > 1) {
columns.unshift({
field: 'job_id',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*/

import PropTypes from 'prop-types';
import _ from 'lodash';
import get from 'lodash/get';

import React, { Component } from 'react';

Expand Down Expand Up @@ -70,7 +70,7 @@ class AnomaliesTable extends Component {
} else {
const examples =
item.entityName === 'mlcategory'
? _.get(this.props.tableData, ['examplesByJobId', item.jobId, item.entityValue])
? get(this.props.tableData, ['examplesByJobId', item.jobId, item.entityValue])
: undefined;
let definition = undefined;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import { EuiButtonIcon, EuiLink, EuiScreenReaderOnly } from '@elastic/eui';

import React from 'react';
import _ from 'lodash';
import get from 'lodash/get';

import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
Expand Down Expand Up @@ -251,7 +251,7 @@ export function getColumns(
sortable: false,
truncateText: true,
render: (item) => {
const examples = _.get(examplesByJobId, [item.jobId, item.entityValue], []);
const examples = get(examplesByJobId, [item.jobId, item.entityValue], []);
return (
<EuiLink
className="mlAnomalyCategoryExamples__link"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@

import PropTypes from 'prop-types';
import React, { Component, Fragment } from 'react';
import _ from 'lodash';
import get from 'lodash/get';
import pick from 'lodash/pick';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';

Expand Down Expand Up @@ -63,16 +64,12 @@ function getDetailsItems(anomaly, examples, filter) {
}
} else {
causes = sourceCauses.map((cause) => {
const simplified = _.pick(cause, 'typical', 'actual', 'probability');
const simplified = pick(cause, 'typical', 'actual', 'probability');
// Get the 'entity field name/value' to display in the cause -
// For by and over, use by_field_name/value (over_field_name/value are in the top level fields)
// For just an 'over' field - the over_field_name/value appear in both top level and cause.
simplified.entityName = _.has(cause, 'by_field_name')
? cause.by_field_name
: cause.over_field_name;
simplified.entityValue = _.has(cause, 'by_field_value')
? cause.by_field_value
: cause.over_field_value;
simplified.entityName = cause.by_field_name ? cause.by_field_name : cause.over_field_name;
simplified.entityValue = cause.by_field_value ? cause.by_field_value : cause.over_field_value;
return simplified;
});
}
Expand Down Expand Up @@ -471,7 +468,7 @@ export class AnomalyDetails extends Component {

renderDetails() {
const detailItems = getDetailsItems(this.props.anomaly, this.props.examples, this.props.filter);
const isInterimResult = _.get(this.props.anomaly, 'source.is_interim', false);
const isInterimResult = get(this.props.anomaly, 'source.is_interim', false);
return (
<React.Fragment>
<EuiText size="xs">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/

import _ from 'lodash';
import each from 'lodash/each';
import PropTypes from 'prop-types';
import React, { Component } from 'react';

Expand Down Expand Up @@ -148,7 +148,7 @@ export class InfluencersCell extends Component {

const influencers = [];
recordInfluencers.forEach((influencer) => {
_.each(influencer, (influencerFieldValue, influencerFieldName) => {
each(influencer, (influencerFieldValue, influencerFieldName) => {
influencers.push({
influencerFieldName,
influencerFieldValue,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/

import _ from 'lodash';
import cloneDeep from 'lodash/cloneDeep';
import moment from 'moment';
import rison from 'rison-node';
import PropTypes from 'prop-types';
Expand Down Expand Up @@ -58,7 +58,7 @@ class LinksMenuUI extends Component {

// If url_value contains $earliest$ and $latest$ tokens, add in times to the source record.
// Create a copy of the record as we are adding properties into it.
const record = _.cloneDeep(anomaly.source);
const record = cloneDeep(anomaly.source);
const timestamp = record.timestamp;
const configuredUrlValue = customUrl.url_value;
const timeRangeInterval = parseInterval(customUrl.time_range);
Expand Down Expand Up @@ -99,7 +99,7 @@ class LinksMenuUI extends Component {
if (
(configuredUrlValue.includes('$mlcategoryterms$') ||
configuredUrlValue.includes('$mlcategoryregex$')) &&
_.has(record, 'mlcategory')
record.mlcategory !== undefined
) {
const jobId = record.job_id;

Expand Down Expand Up @@ -156,15 +156,15 @@ class LinksMenuUI extends Component {
// Extract the by, over and partition fields for the record.
const entityCondition = {};

if (_.has(record, 'partition_field_value')) {
if (record.partition_field_value !== undefined) {
entityCondition[record.partition_field_name] = record.partition_field_value;
}

if (_.has(record, 'over_field_value')) {
if (record.over_field_value !== undefined) {
entityCondition[record.over_field_name] = record.over_field_value;
}

if (_.has(record, 'by_field_value')) {
if (record.by_field_value !== undefined) {
// Note that analyses with by and over fields, will have a top-level by_field_name,
// but the by_field_value(s) will be in the nested causes array.
// TODO - drilldown from cause in expanded row only?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
* the raw data in the Explorer dashboard.
*/

import _ from 'lodash';

import { parseInterval } from '../../../../common/util/parse_interval';
import { getEntityFieldList } from '../../../../common/util/anomaly_utils';
import { buildConfigFromDetector } from '../../util/chart_config_builder';
Expand All @@ -30,7 +28,7 @@ export function buildConfig(record) {

config.detectorLabel = record.function;
if (
_.has(mlJobService.detectorsByJob, record.job_id) &&
mlJobService.detectorsByJob[record.job_id] !== undefined &&
detectorIndex < mlJobService.detectorsByJob[record.job_id].length
) {
config.detectorLabel =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@

import PropTypes from 'prop-types';
import React from 'react';
import { i18n } from '@kbn/i18n';

import _ from 'lodash';
import d3 from 'd3';
import $ from 'jquery';
import moment from 'moment';
Expand All @@ -33,8 +33,6 @@ import { mlFieldFormatService } from '../../services/field_format_service';

import { CHART_TYPE } from '../explorer_constants';

import { i18n } from '@kbn/i18n';

const CONTENT_WRAPPER_HEIGHT = 215;

// If a rare/event-distribution chart has a cardinality of 10 or less,
Expand Down Expand Up @@ -403,7 +401,7 @@ export class ExplorerChartDistribution extends React.Component {
.attr('cy', (d) => lineChartYScale(d[CHART_Y_ATTRIBUTE]))
.attr('class', (d) => {
let markerClass = 'metric-value';
if (_.has(d, 'anomalyScore') && Number(d.anomalyScore) >= severity) {
if (d.anomalyScore !== undefined && Number(d.anomalyScore) >= severity) {
markerClass += ' anomaly-marker ';
markerClass += getSeverityWithLow(d.anomalyScore).id;
}
Expand Down Expand Up @@ -444,7 +442,7 @@ export class ExplorerChartDistribution extends React.Component {
const tooltipData = [{ label: formattedDate }];
const seriesKey = config.detectorLabel;

if (_.has(marker, 'entity')) {
if (marker.entity !== undefined) {
tooltipData.push({
label: i18n.translate('xpack.ml.explorer.distributionChart.entityLabel', {
defaultMessage: 'entity',
Expand All @@ -457,7 +455,7 @@ export class ExplorerChartDistribution extends React.Component {
});
}

if (_.has(marker, 'anomalyScore')) {
if (marker.anomalyScore !== undefined) {
const score = parseInt(marker.anomalyScore);
const displayScore = score > 0 ? score : '< 1';
tooltipData.push({
Expand Down Expand Up @@ -494,7 +492,7 @@ export class ExplorerChartDistribution extends React.Component {
valueAccessor: 'typical',
});
}
if (typeof marker.byFieldName !== 'undefined' && _.has(marker, 'numberOfCauses')) {
if (typeof marker.byFieldName !== 'undefined' && marker.numberOfCauses !== undefined) {
tooltipData.push({
label: i18n.translate(
'xpack.ml.explorer.distributionChart.unusualByFieldValuesLabel',
Expand Down Expand Up @@ -532,7 +530,7 @@ export class ExplorerChartDistribution extends React.Component {
});
}

if (_.has(marker, 'scheduledEvents')) {
if (marker.scheduledEvents !== undefined) {
marker.scheduledEvents.forEach((scheduledEvent, i) => {
tooltipData.push({
label: i18n.translate(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
import PropTypes from 'prop-types';
import React from 'react';

import _ from 'lodash';
import d3 from 'd3';
import $ from 'jquery';
import moment from 'moment';
import { i18n } from '@kbn/i18n';

import { formatHumanReadableDateTime } from '../../util/date_utils';
import { formatValue } from '../../formatters/format_value';
Expand All @@ -40,8 +40,6 @@ import { getTimeBucketsFromCache } from '../../util/time_buckets';
import { mlEscape } from '../../util/string_utils';
import { mlFieldFormatService } from '../../services/field_format_service';

import { i18n } from '@kbn/i18n';

const CONTENT_WRAPPER_HEIGHT = 215;
const CONTENT_WRAPPER_CLASS = 'ml-explorer-chart-content-wrapper';

Expand Down Expand Up @@ -307,7 +305,7 @@ export class ExplorerChartSingleMetric extends React.Component {
.on('mouseout', () => tooltipService.hide());

const isAnomalyVisible = (d) =>
_.has(d, 'anomalyScore') && Number(d.anomalyScore) >= severity;
d.anomalyScore !== undefined && Number(d.anomalyScore) >= severity;

// Update all dots to new positions.
dots
Expand Down Expand Up @@ -380,7 +378,7 @@ export class ExplorerChartSingleMetric extends React.Component {
const tooltipData = [{ label: formattedDate }];
const seriesKey = config.detectorLabel;

if (_.has(marker, 'anomalyScore')) {
if (marker.anomalyScore !== undefined) {
const score = parseInt(marker.anomalyScore);
const displayScore = score > 0 ? score : '< 1';
tooltipData.push({
Expand Down Expand Up @@ -411,7 +409,7 @@ export class ExplorerChartSingleMetric extends React.Component {
// Show actual/typical when available except for rare detectors.
// Rare detectors always have 1 as actual and the probability as typical.
// Exposing those values in the tooltip with actual/typical labels might irritate users.
if (_.has(marker, 'actual') && config.functionDescription !== 'rare') {
if (marker.actual !== undefined && config.functionDescription !== 'rare') {
// Display the record actual in preference to the chart value, which may be
// different depending on the aggregation interval of the chart.
tooltipData.push({
Expand Down Expand Up @@ -445,7 +443,7 @@ export class ExplorerChartSingleMetric extends React.Component {
},
valueAccessor: 'value',
});
if (_.has(marker, 'byFieldName') && _.has(marker, 'numberOfCauses')) {
if (marker.byFieldName !== undefined && marker.numberOfCauses !== undefined) {
tooltipData.push({
label: i18n.translate(
'xpack.ml.explorer.distributionChart.unusualByFieldValuesLabel',
Expand Down Expand Up @@ -483,7 +481,7 @@ export class ExplorerChartSingleMetric extends React.Component {
});
}

if (_.has(marker, 'scheduledEvents')) {
if (marker.scheduledEvents !== undefined) {
tooltipData.push({
label: i18n.translate('xpack.ml.explorer.singleMetricChart.scheduledEventsLabel', {
defaultMessage: 'Scheduled events',
Expand Down
Loading

0 comments on commit a81059b

Please sign in to comment.