mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[ML] Adds support for kuery to job wizards (#26094)
* [ML] Adds support for kuery to job wizards * [ML] Pass combined query and filters to multi metric model mem calc * [ML] Edits following review
This commit is contained in:
parent
56e27e6c8c
commit
445ac2f12f
20 changed files with 163 additions and 190 deletions
|
@ -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();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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';
|
||||
|
@ -53,7 +53,6 @@ const module = uiModules.get('apps/ml');
|
|||
module
|
||||
.controller('MlDataVisualizerViewFields', function (
|
||||
$scope,
|
||||
$route,
|
||||
$timeout,
|
||||
$window,
|
||||
Private,
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
|
|
|
@ -7,10 +7,6 @@
|
|||
|
||||
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(() => {
|
||||
|
@ -18,13 +14,15 @@ describe('ML - Advanced Job Wizard - New Job Controller', () => {
|
|||
});
|
||||
|
||||
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 });
|
||||
|
||||
|
@ -32,7 +30,6 @@ describe('ML - Advanced Job Wizard - New Job Controller', () => {
|
|||
// 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();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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,
|
||||
|
@ -76,6 +76,7 @@ module.controller('MlNewJob',
|
|||
$route,
|
||||
$location,
|
||||
$modal,
|
||||
Private,
|
||||
mlDatafeedService,
|
||||
mlConfirmModalService) {
|
||||
|
||||
|
@ -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);
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
@ -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();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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';
|
||||
|
@ -64,7 +64,6 @@ const module = uiModules.get('apps/ml');
|
|||
module
|
||||
.controller('MlCreateMultiMetricJob', function (
|
||||
$scope,
|
||||
$route,
|
||||
$timeout,
|
||||
Private,
|
||||
AppState) {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
@ -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();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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';
|
||||
|
@ -63,7 +63,6 @@ const module = uiModules.get('apps/ml');
|
|||
module
|
||||
.controller('MlCreatePopulationJob', function (
|
||||
$scope,
|
||||
$route,
|
||||
$timeout,
|
||||
Private,
|
||||
AppState) {
|
||||
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -8,10 +8,7 @@
|
|||
|
||||
import ngMock from 'ng_mock';
|
||||
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';
|
||||
|
||||
describe('ML - Recognize Wizard - Create Job Controller', () => {
|
||||
beforeEach(() => {
|
||||
|
@ -19,12 +16,15 @@ describe('ML - Recognize Wizard - Create Job Controller', () => {
|
|||
});
|
||||
|
||||
it('Initialize Create Job Controller', (done) => {
|
||||
const stub = sinon.stub(newJobUtils, 'createSearchItems').callsFake(() => ({
|
||||
indexPattern: {},
|
||||
savedSearch: {},
|
||||
combinedQuery: {}
|
||||
}));
|
||||
ngMock.inject(function ($rootScope, $controller) {
|
||||
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('MlCreateRecognizerJobs', {
|
||||
$route: {
|
||||
|
@ -36,7 +36,6 @@ describe('ML - Recognize Wizard - Create Job Controller', () => {
|
|||
});
|
||||
|
||||
expect(scope.ui.formValid).to.eql(true);
|
||||
stub.restore();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -10,7 +10,7 @@ import _ from 'lodash';
|
|||
import angular from 'angular';
|
||||
import dateMath from '@kbn/datemath';
|
||||
import { isJobIdValid, prefixDatafeedId } from 'plugins/ml/../common/util/job_utils';
|
||||
import { createSearchItems, addNewJobToRecentlyAccessed } from 'plugins/ml/jobs/new_job/utils/new_job_utils';
|
||||
import { SearchItemsProvider, addNewJobToRecentlyAccessed } from 'plugins/ml/jobs/new_job/utils/new_job_utils';
|
||||
|
||||
|
||||
import uiRoutes from 'ui/routes';
|
||||
|
@ -81,11 +81,12 @@ module
|
|||
const moduleId = $route.current.params.id;
|
||||
$scope.moduleId = moduleId;
|
||||
|
||||
const createSearchItems = Private(SearchItemsProvider);
|
||||
const {
|
||||
indexPattern,
|
||||
savedSearch,
|
||||
query,
|
||||
combinedQuery } = createSearchItems($route);
|
||||
combinedQuery } = createSearchItems();
|
||||
|
||||
const pageTitle = (savedSearch.id !== undefined) ?
|
||||
`saved search ${savedSearch.title}` : `index pattern ${indexPattern.title}`;
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
*/
|
||||
|
||||
|
||||
|
||||
import { getQueryFromSavedSearch } from 'plugins/ml/jobs/new_job/utils/new_job_utils';
|
||||
import { SavedObjectsClientProvider } from 'ui/saved_objects';
|
||||
import { mlJobService } from 'plugins/ml/services/job_service';
|
||||
import { ml } from 'plugins/ml/services/ml_api_service';
|
||||
|
@ -41,7 +39,7 @@ export function CreateRecognizerJobsServiceProvider(Private) {
|
|||
}
|
||||
|
||||
indexTimeRange(indexPattern, formConfig) {
|
||||
const query = getQueryFromSavedSearch(formConfig);
|
||||
const query = formConfig.combinedQuery;
|
||||
return ml.getTimeFieldRange({
|
||||
index: indexPattern.title,
|
||||
timeFieldName: indexPattern.timeFieldName,
|
||||
|
|
|
@ -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';
|
||||
|
||||
describe('ML - Single Metric Wizard - Create Job Controller', () => {
|
||||
|
@ -20,13 +19,16 @@ describe('ML - Single 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);
|
||||
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: {},
|
||||
savedSearch: {}
|
||||
}
|
||||
};
|
||||
|
||||
const scope = $rootScope.$new();
|
||||
$controller('MlCreateSingleMetricJob', {
|
||||
$route: {
|
||||
|
@ -38,8 +40,7 @@ describe('ML - Single Metric Wizard - Create Job Controller', () => {
|
|||
});
|
||||
|
||||
expect(scope.ui.showJobInput).to.eql(false);
|
||||
stub1.restore();
|
||||
stub2.restore();
|
||||
stub.restore();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -30,7 +30,7 @@ import { loadCurrentIndexPattern, loadCurrentSavedSearch, timeBasedIndexCheck }
|
|||
import { checkMlNodesAvailable } from 'plugins/ml/ml_nodes_check/check_ml_nodes';
|
||||
import { loadNewJobDefaults } from 'plugins/ml/jobs/new_job/utils/new_job_defaults';
|
||||
import {
|
||||
createSearchItems,
|
||||
SearchItemsProvider,
|
||||
addNewJobToRecentlyAccessed,
|
||||
moveToAdvancedJobCreationProvider,
|
||||
focusOnResultsLink } from 'plugins/ml/jobs/new_job/utils/new_job_utils';
|
||||
|
@ -114,12 +114,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);
|
||||
|
||||
|
|
|
@ -132,12 +132,7 @@ export function SingleMetricJobServiceProvider() {
|
|||
function: func
|
||||
};
|
||||
|
||||
let query = {
|
||||
match_all: {}
|
||||
};
|
||||
if (formConfig.query.query_string.query !== '*' || formConfig.filters.length) {
|
||||
query = formConfig.combinedQuery;
|
||||
}
|
||||
const query = formConfig.combinedQuery;
|
||||
|
||||
if (formConfig.field && formConfig.field.id) {
|
||||
dtr.field_name = formConfig.field.id;
|
||||
|
|
|
@ -8,85 +8,63 @@
|
|||
|
||||
import _ from 'lodash';
|
||||
import $ from 'jquery';
|
||||
import { migrateFilter } from '@kbn/es-query';
|
||||
import { BuildESQueryProvider } from '@kbn/es-query';
|
||||
import { addItemToRecentlyAccessed } from 'plugins/ml/util/recently_accessed';
|
||||
import { mlJobService } from 'plugins/ml/services/job_service';
|
||||
|
||||
export function getQueryFromSavedSearch(formConfig) {
|
||||
const must = [];
|
||||
const mustNot = [];
|
||||
|
||||
must.push(formConfig.query);
|
||||
// Provider for creating the items used for searching and job creation.
|
||||
// Uses the $route object to retrieve the indexPattern and savedSearch from the url
|
||||
export function SearchItemsProvider(Private, $route) {
|
||||
|
||||
formConfig.filters.forEach((f) => {
|
||||
let query = (f.query || f);
|
||||
query = _.omit(query, ['meta', '$state']);
|
||||
query = migrateFilter(query);
|
||||
const buildESQuery = Private(BuildESQueryProvider);
|
||||
|
||||
if(f.meta.disabled === false) {
|
||||
if(f.meta.negate) {
|
||||
mustNot.push(query);
|
||||
} else {
|
||||
must.push(query);
|
||||
function createSearchItems() {
|
||||
let indexPattern = $route.current.locals.indexPattern;
|
||||
|
||||
let query = {
|
||||
query: '*',
|
||||
language: 'lucene'
|
||||
};
|
||||
|
||||
let combinedQuery = {
|
||||
bool: {
|
||||
must: [{
|
||||
query_string: {
|
||||
analyze_wildcard: true,
|
||||
query: '*'
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
bool: {
|
||||
must,
|
||||
must_not: mustNot
|
||||
}
|
||||
};
|
||||
}
|
||||
let filters = [];
|
||||
|
||||
// create items used for searching and job creation.
|
||||
// takes the $route object to retrieve the indexPattern and savedSearch from the url
|
||||
export function createSearchItems($route) {
|
||||
let indexPattern = $route.current.locals.indexPattern;
|
||||
const query = {
|
||||
query_string: {
|
||||
analyze_wildcard: true,
|
||||
query: '*'
|
||||
}
|
||||
};
|
||||
const savedSearch = $route.current.locals.savedSearch;
|
||||
if (indexPattern.id === undefined && savedSearch.id !== undefined) {
|
||||
const searchSource = savedSearch.searchSource;
|
||||
indexPattern = searchSource.getField('index');
|
||||
|
||||
let filters = [];
|
||||
const savedSearch = $route.current.locals.savedSearch;
|
||||
const searchSource = savedSearch.searchSource;
|
||||
query = searchSource.getField('query');
|
||||
const fs = searchSource.getField('filter');
|
||||
|
||||
if (indexPattern.id === undefined &&
|
||||
savedSearch.id !== undefined) {
|
||||
indexPattern = searchSource.getField('index');
|
||||
|
||||
// Extract the query from the searchSource
|
||||
// Might be as a String in q.query, or
|
||||
// nested inside q.query.query_string
|
||||
const q = searchSource.getField('query');
|
||||
if (q !== undefined && q.language === 'lucene' && q.query !== undefined) {
|
||||
if (typeof q.query === 'string' && q.query !== '') {
|
||||
query.query_string.query = q.query;
|
||||
} else if (typeof q.query === 'object' &&
|
||||
typeof q.query.query_string === 'object' && q.query.query_string.query !== '') {
|
||||
query.query_string.query = q.query.query_string.query;
|
||||
if (fs.length) {
|
||||
filters = fs;
|
||||
}
|
||||
|
||||
combinedQuery = buildESQuery(indexPattern, [query], filters);
|
||||
}
|
||||
|
||||
const fs = searchSource.getField('filter');
|
||||
if (fs.length) {
|
||||
filters = fs;
|
||||
}
|
||||
|
||||
return {
|
||||
indexPattern,
|
||||
savedSearch,
|
||||
filters,
|
||||
query,
|
||||
combinedQuery
|
||||
};
|
||||
}
|
||||
const combinedQuery = getQueryFromSavedSearch({ query, filters });
|
||||
|
||||
return {
|
||||
indexPattern,
|
||||
savedSearch,
|
||||
filters,
|
||||
query,
|
||||
combinedQuery
|
||||
};
|
||||
return createSearchItems;
|
||||
}
|
||||
|
||||
export function createJobForSaving(job) {
|
||||
|
|
|
@ -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';
|
||||
|
||||
describe('ML - Job Type Controller', () => {
|
||||
|
@ -20,19 +19,24 @@ describe('ML - Job Type Controller', () => {
|
|||
});
|
||||
|
||||
it('Initialize Job Type 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: 'test_id',
|
||||
title: 'test_pattern'
|
||||
},
|
||||
savedSearch: {}
|
||||
}
|
||||
};
|
||||
|
||||
const scope = $rootScope.$new();
|
||||
$controller('MlNewJobStepJobType', { $scope: scope });
|
||||
|
||||
expect(scope.indexWarningTitle).to.eql('Index pattern undefined is not time based');
|
||||
stub1.restore();
|
||||
stub2.restore();
|
||||
expect(scope.indexWarningTitle).to.eql('Index pattern test_pattern is not time based');
|
||||
stub.restore();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
import uiRoutes from 'ui/routes';
|
||||
import { checkLicenseExpired } from 'plugins/ml/license/check_license';
|
||||
import { checkCreateJobsPrivilege } 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 { addItemToRecentlyAccessed } from 'plugins/ml/util/recently_accessed';
|
||||
import { checkMlNodesAvailable } from 'plugins/ml/ml_nodes_check/check_ml_nodes';
|
||||
|
@ -42,14 +42,15 @@ const module = uiModules.get('apps/ml');
|
|||
module.controller('MlNewJobStepJobType',
|
||||
function (
|
||||
$scope,
|
||||
$route) {
|
||||
Private) {
|
||||
|
||||
timefilter.disableTimeRangeSelector(); // remove time picker from top of page
|
||||
timefilter.disableAutoRefreshSelector(); // remove time picker from top of page
|
||||
|
||||
const createSearchItems = Private(SearchItemsProvider);
|
||||
const {
|
||||
indexPattern,
|
||||
savedSearch } = createSearchItems($route);
|
||||
savedSearch } = createSearchItems();
|
||||
|
||||
// check to see that the index pattern is time based.
|
||||
// if it isn't, display a warning and disable all links
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue