Skip to content

Commit

Permalink
[ML] Adds support for kuery to job wizards (#26094)
Browse files Browse the repository at this point in the history
* [ML] Adds support for kuery to job wizards

* [ML] Pass combined query and filters to multi metric model mem calc

* [ML] Edits following review
  • Loading branch information
peteharverson authored Nov 23, 2018
1 parent 56e27e6 commit 445ac2f
Show file tree
Hide file tree
Showing 20 changed files with 163 additions and 190 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,35 @@ import expect from 'expect.js';
import sinon from 'sinon';

// Import this way to be able to stub/mock functions later on in the tests using sinon.
import * as newJobUtils from 'plugins/ml/jobs/new_job/utils/new_job_utils';
import * as indexUtils from 'plugins/ml/util/index_utils';

describe('ML - Data Visualizer View Fields Controller', () => {


beforeEach(() => {
ngMock.module('kibana');
});

it('Initialize Data Visualizer View Fields Controller', (done) => {
const stub1 = sinon.stub(newJobUtils, 'createSearchItems').callsFake(() => ({
indexPattern: {},
savedSearch: {},
combinedQuery: {}
}));
const stub2 = sinon.stub(indexUtils, 'timeBasedIndexCheck').callsFake(() => false);
ngMock.inject(function ($rootScope, $controller) {
const stub = sinon.stub(indexUtils, 'timeBasedIndexCheck').callsFake(() => false);
ngMock.inject(function ($rootScope, $controller, $route) {
// Set up the $route current props required for the tests.
$route.current = {
locals: {
indexPattern: {
id: ''
},
savedSearch: {
id: ''
}
}
};

const scope = $rootScope.$new();
$controller('MlDataVisualizerViewFields', { $scope: scope });

expect(scope.metricCards).to.eql([]);
stub1.restore();
stub2.restore();
stub.restore();
done();
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ import 'plugins/ml/components/form_filter_input';

import chrome from 'ui/chrome';
import uiRoutes from 'ui/routes';
import { notify } from 'ui/notify';
import { decorateQuery, luceneStringToDsl } from '@kbn/es-query';
import { notify, toastNotifications } from 'ui/notify';

import { ML_JOB_FIELD_TYPES, KBN_FIELD_TYPES } from 'plugins/ml/../common/constants/field_types';
import { kbnTypeToMLJobType } from 'plugins/ml/util/field_types_utils';
import { IntervalHelperProvider } from 'plugins/ml/util/ml_time_buckets';
import { checkBasicLicense, isFullLicense } from 'plugins/ml/license/check_license';
import { checkGetJobsPrivilege } from 'plugins/ml/privilege/check_privilege';
import { createSearchItems } from 'plugins/ml/jobs/new_job/utils/new_job_utils';
import { SearchItemsProvider } from 'plugins/ml/jobs/new_job/utils/new_job_utils';
import { loadCurrentIndexPattern, loadCurrentSavedSearch, timeBasedIndexCheck } from 'plugins/ml/util/index_utils';
import { checkMlNodesAvailable } from 'plugins/ml/ml_nodes_check/check_ml_nodes';
import { ml } from 'plugins/ml/services/ml_api_service';
Expand All @@ -53,7 +53,6 @@ const module = uiModules.get('apps/ml');
module
.controller('MlDataVisualizerViewFields', function (
$scope,
$route,
$timeout,
$window,
Private,
Expand All @@ -62,9 +61,12 @@ module

timefilter.enableTimeRangeSelector();
timefilter.enableAutoRefreshSelector();

const createSearchItems = Private(SearchItemsProvider);
const {
indexPattern,
query } = createSearchItems($route);
query } = createSearchItems();

timeBasedIndexCheck(indexPattern, true);

// List of system fields we don't want to display.
Expand Down Expand Up @@ -97,20 +99,16 @@ module
$scope.showSidebar = isFullLicense();

// Check for a saved query in the AppState or via a savedSearchId in the URL.
// TODO - add in support for lucene queries with filters and Kuery.
$scope.searchQueryText = '';
if (_.has($scope.appState, 'query')) {
// Currently only support lucene syntax.
if (_.get($scope.appState, 'query.language') === 'lucene') {
$scope.searchQueryText = _.get($scope.appState, 'query.query', '');
}
const queryBarQry = ($scope.appState.query !== undefined) ? ($scope.appState.query) : query;
if (queryBarQry.language === 'lucene') {
$scope.searchQueryText = _.get(queryBarQry, 'query', '');
} else {
// Use the query built from the savedSearchId supplied in the URL.
// If no savedSearchId, the query will default to '*'.
// TODO - when filtering is supported, use the filters part too.
const queryString = _.get(query, 'query_string.query', '');
if (queryString !== '*') {
$scope.searchQueryText = queryString;
}
toastNotifications.addWarning({
title: `${(queryBarQry.language !== undefined) ? queryBarQry.language : ''} syntax not supported`,
text: 'The Data Visualizer currently only supports queries using the lucene query syntax.',
});
}

$scope.searchQuery = buildSearchQuery();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,29 @@

import ngMock from 'ng_mock';
import expect from 'expect.js';
import sinon from 'sinon';

// Import this way to be able to stub/mock `createSearchItems` later on in the test using sinon.
import * as newJobUtils from 'plugins/ml/jobs/new_job/utils/new_job_utils';

describe('ML - Advanced Job Wizard - New Job Controller', () => {
beforeEach(() => {
ngMock.module('kibana');
});

it('Initialize New Job Controller', (done) => {
const stub = sinon.stub(newJobUtils, 'createSearchItems').callsFake(() => ({
indexPattern: {},
savedSearch: {},
combinedQuery: {}
}));
ngMock.inject(function ($rootScope, $controller, $route) {
// Set up the $route current props required for the tests.
$route.current = {
locals: {
indexPattern: {},
savedSearch: {}
}
};

ngMock.inject(function ($rootScope, $controller) {
const scope = $rootScope.$new();
$controller('MlNewJob', { $scope: scope });

// This is just about initializing the controller and making sure
// all angularjs based dependencies get loaded without error.
// This simple scope test is just a final sanity check.
expect(scope.ui.pageTitle).to.be('Create a new job');
stub.restore();
done();
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { checkCreateJobsPrivilege } from 'plugins/ml/privilege/check_privilege';
import template from './new_job.html';
import saveStatusTemplate from 'plugins/ml/jobs/new_job/advanced/save_status_modal/save_status_modal.html';
import {
createSearchItems,
SearchItemsProvider,
createJobForSaving,
checkCardinalitySuccess,
getMinimalValidJob,
Expand Down Expand Up @@ -76,6 +76,7 @@ module.controller('MlNewJob',
$route,
$location,
$modal,
Private,
mlDatafeedService,
mlConfirmModalService) {

Expand Down Expand Up @@ -614,10 +615,11 @@ module.controller('MlNewJob',
// if an index pattern or saved search has been added to the url
// populate those items in the form and datafeed config
function populateFormFromUrl() {
const createSearchItems = Private(SearchItemsProvider);
const {
indexPattern,
savedSearch,
combinedQuery } = createSearchItems($route);
combinedQuery } = createSearchItems();

if (indexPattern.id !== undefined) {
timeBasedIndexCheck(indexPattern, true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import React from 'react';
import ReactDOM from 'react-dom';

import { BucketSpanEstimator } from './bucket_span_estimator_view';
import { getQueryFromSavedSearch } from 'plugins/ml/jobs/new_job/utils/new_job_utils';
import { EVENT_RATE_COUNT_FIELD } from 'plugins/ml/jobs/new_job/simple/components/constants/general';
import { ml } from 'plugins/ml/services/ml_api_service';

Expand Down Expand Up @@ -57,7 +56,7 @@ module.directive('mlBucketSpanEstimator', function () {
fields: [],
filters: $scope.formConfig.filters,
index: $scope.formConfig.indexPattern.title,
query: getQueryFromSavedSearch($scope.formConfig),
query: $scope.formConfig.combinedQuery,
splitField: $scope.formConfig.splitField && $scope.formConfig.splitField.name,
timeField: $scope.formConfig.timeField
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import expect from 'expect.js';
import sinon from 'sinon';

// Import this way to be able to stub/mock functions later on in the tests using sinon.
import * as newJobUtils from 'plugins/ml/jobs/new_job/utils/new_job_utils';
import * as indexUtils from 'plugins/ml/util/index_utils';
import * as utils from 'plugins/ml/jobs/new_job/simple/components/utils/create_fields';

Expand All @@ -21,21 +20,23 @@ describe('ML - Multi Metric Wizard - Create Job Controller', () => {
});

it('Initialize Create Job Controller', (done) => {
const stub1 = sinon.stub(newJobUtils, 'createSearchItems').callsFake(() => ({
indexPattern: {},
savedSearch: {},
combinedQuery: {}
}));
const stub2 = sinon.stub(indexUtils, 'timeBasedIndexCheck').callsFake(() => false);
const stub3 = sinon.stub(utils, 'createFields').callsFake(() => false);
ngMock.inject(function ($rootScope, $controller) {
const stub1 = sinon.stub(indexUtils, 'timeBasedIndexCheck').callsFake(() => false);
const stub2 = sinon.stub(utils, 'createFields').callsFake(() => false);
ngMock.inject(function ($rootScope, $controller, $route) {
// Set up the $route current props required for the tests.
$route.current = {
locals: {
indexPattern: {},
savedSearch: {}
}
};

const scope = $rootScope.$new();
$controller('MlCreateMultiMetricJob', { $scope: scope });

expect(typeof scope.ui).to.eql('object');
stub1.restore();
stub2.restore();
stub3.restore();
done();
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { checkMlNodesAvailable } from 'plugins/ml/ml_nodes_check/check_ml_nodes'
import { loadNewJobDefaults } from 'plugins/ml/jobs/new_job/utils/new_job_defaults';
import { mlEscape } from 'plugins/ml/util/string_utils';
import {
createSearchItems,
SearchItemsProvider,
addNewJobToRecentlyAccessed,
moveToAdvancedJobCreationProvider,
focusOnResultsLink } from 'plugins/ml/jobs/new_job/utils/new_job_utils';
Expand Down Expand Up @@ -64,7 +64,6 @@ const module = uiModules.get('apps/ml');
module
.controller('MlCreateMultiMetricJob', function (
$scope,
$route,
$timeout,
Private,
AppState) {
Expand Down Expand Up @@ -109,12 +108,13 @@ module
// flag to stop all results polling if the user navigates away from this page
let globalForceStop = false;

const createSearchItems = Private(SearchItemsProvider);
const {
indexPattern,
savedSearch,
query,
filters,
combinedQuery } = createSearchItems($route);
combinedQuery } = createSearchItems();

timeBasedIndexCheck(indexPattern, true);

Expand Down Expand Up @@ -642,7 +642,7 @@ module
ml.calculateModelMemoryLimit({
indexPattern: formConfig.indexPattern.title,
splitFieldName: formConfig.splitField.name,
query: formConfig.query,
query: formConfig.combinedQuery,
fieldNames: Object.keys(formConfig.fields),
influencerNames: formConfig.influencerFields.map(f => f.name),
timeFieldName: formConfig.timeField,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,12 +212,7 @@ export function MultiMetricJobServiceProvider() {
job.analysis_config.influencers = influencerFields;
}

let query = {
match_all: {}
};
if (formConfig.query.query_string.query !== '*' || formConfig.filters.length) {
query = formConfig.combinedQuery;
}
const query = formConfig.combinedQuery;

job.analysis_config.bucket_span = formConfig.bucketSpan;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import expect from 'expect.js';
import sinon from 'sinon';

// Import this way to be able to stub/mock functions later on in the tests using sinon.
import * as newJobUtils from 'plugins/ml/jobs/new_job/utils/new_job_utils';
import * as indexUtils from 'plugins/ml/util/index_utils';
import * as utils from 'plugins/ml/jobs/new_job/simple/components/utils/create_fields';

Expand All @@ -21,21 +20,23 @@ describe('ML - Population Wizard - Create Job Controller', () => {
});

it('Initialize Create Job Controller', (done) => {
const stub1 = sinon.stub(newJobUtils, 'createSearchItems').callsFake(() => ({
indexPattern: {},
savedSearch: {},
combinedQuery: {}
}));
const stub2 = sinon.stub(indexUtils, 'timeBasedIndexCheck').callsFake(() => false);
const stub3 = sinon.stub(utils, 'createFields').callsFake(() => false);
ngMock.inject(function ($rootScope, $controller) {
const stub1 = sinon.stub(indexUtils, 'timeBasedIndexCheck').callsFake(() => false);
const stub2 = sinon.stub(utils, 'createFields').callsFake(() => false);
ngMock.inject(function ($rootScope, $controller, $route) {
// Set up the $route current props required for the tests.
$route.current = {
locals: {
indexPattern: {},
savedSearch: {}
}
};

const scope = $rootScope.$new();
$controller('MlCreatePopulationJob', { $scope: scope });

expect(typeof scope.ui).to.eql('object');
stub1.restore();
stub2.restore();
stub3.restore();
done();
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { checkMlNodesAvailable } from 'plugins/ml/ml_nodes_check/check_ml_nodes'
import { loadNewJobDefaults, newJobDefaults } from 'plugins/ml/jobs/new_job/utils/new_job_defaults';
import { mlEscape } from 'plugins/ml/util/string_utils';
import {
createSearchItems,
SearchItemsProvider,
addNewJobToRecentlyAccessed,
moveToAdvancedJobCreationProvider,
focusOnResultsLink } from 'plugins/ml/jobs/new_job/utils/new_job_utils';
Expand Down Expand Up @@ -63,7 +63,6 @@ const module = uiModules.get('apps/ml');
module
.controller('MlCreatePopulationJob', function (
$scope,
$route,
$timeout,
Private,
AppState) {
Expand Down Expand Up @@ -109,12 +108,13 @@ module
// flag to stop all results polling if the user navigates away from this page
let globalForceStop = false;

const createSearchItems = Private(SearchItemsProvider);
const {
indexPattern,
savedSearch,
query,
filters,
combinedQuery } = createSearchItems($route);
combinedQuery } = createSearchItems();

timeBasedIndexCheck(indexPattern, true);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,12 +244,7 @@ export function PopulationJobServiceProvider(Private) {
job.analysis_config.influencers = influencerFields;
}

let query = {
match_all: {}
};
if (formConfig.query.query_string.query !== '*' || formConfig.filters.length) {
query = formConfig.combinedQuery;
}
const query = formConfig.combinedQuery;

job.analysis_config.bucket_span = formConfig.bucketSpan;

Expand Down
Loading

0 comments on commit 445ac2f

Please sign in to comment.