mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
Refactor SearchSource interface (#20334)
* Removed the dynamically assigned type, query, filter, sort, highlight, highlightAll, aggs, from, searchAfter, size, source, version, and fields methods. * The accessor interface now consists of getField and setField methods which throw errors if an unrecognized property name is provided, in addition to getFields, setFields, getOwnField, and getId methods. * Linked-list interface now consists of setParent and getParent. * Factory interface now consists of create, createCopy, and createChild. * Removed the unused unused enable, disable, and addFilterPredicate, and the redundant toString (method only used internally) and extend method (superseded by createChild). * Internally, renamed the _state property to _data and grouped methods by concern.
This commit is contained in:
parent
e308828b83
commit
e024d3dfa1
40 changed files with 627 additions and 662 deletions
|
@ -21,16 +21,16 @@
|
|||
export function createSearchSource(kbnApi, initialState, indexPattern, aggs, useTimeFilter, filters = []) {
|
||||
const searchSource = new kbnApi.SearchSource(initialState);
|
||||
// Do not not inherit from rootSearchSource to avoid picking up time and globals
|
||||
searchSource.inherits(false);
|
||||
searchSource.filter(() => {
|
||||
searchSource.setParent(false);
|
||||
searchSource.setField('filter', () => {
|
||||
const activeFilters = [...filters];
|
||||
if (useTimeFilter) {
|
||||
activeFilters.push(kbnApi.timeFilter.createFilter(indexPattern));
|
||||
}
|
||||
return activeFilters;
|
||||
});
|
||||
searchSource.size(0);
|
||||
searchSource.index(indexPattern);
|
||||
searchSource.aggs(aggs);
|
||||
searchSource.setField('size', 0);
|
||||
searchSource.setField('index', indexPattern);
|
||||
searchSource.setField('aggs', aggs);
|
||||
return searchSource;
|
||||
}
|
||||
|
|
|
@ -39,18 +39,17 @@ export function createSearchSourceStubProvider(hits, timeField) {
|
|||
}),
|
||||
};
|
||||
|
||||
searchSourceStub.filter = sinon.stub().returns(searchSourceStub);
|
||||
searchSourceStub.inherits = sinon.stub().returns(searchSourceStub);
|
||||
searchSourceStub.set = sinon.stub().returns(searchSourceStub);
|
||||
searchSourceStub.get = sinon.spy(key => {
|
||||
const previousSetCall = searchSourceStub.set.withArgs(key).lastCall;
|
||||
searchSourceStub.setParent = sinon.stub().returns(searchSourceStub);
|
||||
searchSourceStub.setField = sinon.stub().returns(searchSourceStub);
|
||||
searchSourceStub.getField = sinon.spy(key => {
|
||||
const previousSetCall = searchSourceStub.setField.withArgs(key).lastCall;
|
||||
return previousSetCall ? previousSetCall.args[1] : null;
|
||||
});
|
||||
searchSourceStub.fetch = sinon.spy(() => {
|
||||
const timeField = searchSourceStub._stubTimeField;
|
||||
const lastQuery = searchSourceStub.set.withArgs('query').lastCall.args[1];
|
||||
const lastQuery = searchSourceStub.setField.withArgs('query').lastCall.args[1];
|
||||
const timeRange = lastQuery.query.constant_score.filter.range[timeField];
|
||||
const lastSort = searchSourceStub.set.withArgs('sort').lastCall.args[1];
|
||||
const lastSort = searchSourceStub.setField.withArgs('sort').lastCall.args[1];
|
||||
const sortDirection = lastSort[0][timeField];
|
||||
const sortFunction =
|
||||
sortDirection === 'asc'
|
||||
|
|
|
@ -26,6 +26,24 @@ import { SearchSourceProvider } from 'ui/courier';
|
|||
|
||||
import { fetchAnchorProvider } from '../anchor';
|
||||
|
||||
function createSearchSourceStubProvider(hits) {
|
||||
const searchSourceStub = {
|
||||
_stubHits: hits,
|
||||
};
|
||||
|
||||
searchSourceStub.setParent = sinon.stub().returns(searchSourceStub);
|
||||
searchSourceStub.setField = sinon.stub().returns(searchSourceStub);
|
||||
searchSourceStub.fetch = sinon.spy(() => Promise.resolve({
|
||||
hits: {
|
||||
hits: searchSourceStub._stubHits,
|
||||
total: searchSourceStub._stubHits.length,
|
||||
},
|
||||
}));
|
||||
|
||||
return function SearchSourceStubProvider() {
|
||||
return searchSourceStub;
|
||||
};
|
||||
}
|
||||
|
||||
describe('context app', function () {
|
||||
beforeEach(ngMock.module('kibana'));
|
||||
|
@ -61,9 +79,9 @@ describe('context app', function () {
|
|||
|
||||
return fetchAnchor('INDEX_PATTERN_ID', 'doc', 'id', [{ '@timestamp': 'desc' }, { '_doc': 'asc' }])
|
||||
.then(() => {
|
||||
const inheritsSpy = searchSourceStub.inherits;
|
||||
expect(inheritsSpy.calledOnce).to.be(true);
|
||||
expect(inheritsSpy.firstCall.args[0]).to.eql(false);
|
||||
const setParentSpy = searchSourceStub.setParent;
|
||||
expect(setParentSpy.calledOnce).to.be(true);
|
||||
expect(setParentSpy.firstCall.args[0]).to.eql(false);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -72,9 +90,8 @@ describe('context app', function () {
|
|||
|
||||
return fetchAnchor('INDEX_PATTERN_ID', 'doc', 'id', [{ '@timestamp': 'desc' }, { '_doc': 'asc' }])
|
||||
.then(() => {
|
||||
const setIndexSpy = searchSourceStub.set.withArgs('index');
|
||||
expect(setIndexSpy.calledOnce).to.be(true);
|
||||
expect(setIndexSpy.firstCall.args[1]).to.eql({ id: 'INDEX_PATTERN_ID' });
|
||||
const setFieldSpy = searchSourceStub.setField;
|
||||
expect(setFieldSpy.firstCall.args[1]).to.eql({ id: 'INDEX_PATTERN_ID' });
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -83,7 +100,7 @@ describe('context app', function () {
|
|||
|
||||
return fetchAnchor('INDEX_PATTERN_ID', 'doc', 'id', [{ '@timestamp': 'desc' }, { '_doc': 'asc' }])
|
||||
.then(() => {
|
||||
const setVersionSpy = searchSourceStub.set.withArgs('version');
|
||||
const setVersionSpy = searchSourceStub.setField.withArgs('version');
|
||||
expect(setVersionSpy.calledOnce).to.be(true);
|
||||
expect(setVersionSpy.firstCall.args[1]).to.eql(true);
|
||||
});
|
||||
|
@ -94,7 +111,7 @@ describe('context app', function () {
|
|||
|
||||
return fetchAnchor('INDEX_PATTERN_ID', 'doc', 'id', [{ '@timestamp': 'desc' }, { '_doc': 'asc' }])
|
||||
.then(() => {
|
||||
const setSizeSpy = searchSourceStub.set.withArgs('size');
|
||||
const setSizeSpy = searchSourceStub.setField.withArgs('size');
|
||||
expect(setSizeSpy.calledOnce).to.be(true);
|
||||
expect(setSizeSpy.firstCall.args[1]).to.eql(1);
|
||||
});
|
||||
|
@ -105,7 +122,7 @@ describe('context app', function () {
|
|||
|
||||
return fetchAnchor('INDEX_PATTERN_ID', 'doc', 'id', [{ '@timestamp': 'desc' }, { '_doc': 'asc' }])
|
||||
.then(() => {
|
||||
const setQuerySpy = searchSourceStub.set.withArgs('query');
|
||||
const setQuerySpy = searchSourceStub.setField.withArgs('query');
|
||||
expect(setQuerySpy.calledOnce).to.be(true);
|
||||
expect(setQuerySpy.firstCall.args[1]).to.eql({
|
||||
query: {
|
||||
|
@ -128,7 +145,7 @@ describe('context app', function () {
|
|||
|
||||
return fetchAnchor('INDEX_PATTERN_ID', 'doc', 'id', [{ '@timestamp': 'desc' }, { '_doc': 'asc' }])
|
||||
.then(() => {
|
||||
const setSortSpy = searchSourceStub.set.withArgs('sort');
|
||||
const setSortSpy = searchSourceStub.setField.withArgs('sort');
|
||||
expect(setSortSpy.calledOnce).to.be(true);
|
||||
expect(setSortSpy.firstCall.args[1]).to.eql([
|
||||
{ '@timestamp': 'desc' },
|
||||
|
@ -167,23 +184,3 @@ describe('context app', function () {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
function createSearchSourceStubProvider(hits) {
|
||||
const searchSourceStub = {
|
||||
_stubHits: hits,
|
||||
};
|
||||
|
||||
searchSourceStub.filter = sinon.stub().returns(searchSourceStub);
|
||||
searchSourceStub.inherits = sinon.stub().returns(searchSourceStub);
|
||||
searchSourceStub.set = sinon.stub().returns(searchSourceStub);
|
||||
searchSourceStub.fetch = sinon.spy(() => Promise.resolve({
|
||||
hits: {
|
||||
hits: searchSourceStub._stubHits,
|
||||
total: searchSourceStub._stubHits.length,
|
||||
},
|
||||
}));
|
||||
|
||||
return function SearchSourceStubProvider() {
|
||||
return searchSourceStub;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ describe('context app', function () {
|
|||
[]
|
||||
)
|
||||
.then((hits) => {
|
||||
const intervals = searchSourceStub.set.args
|
||||
const intervals = searchSourceStub.setField.args
|
||||
.filter(([property]) => property === 'query')
|
||||
.map(([, { query }]) => _.get(query, ['constant_score', 'filter', 'range', '@timestamp']));
|
||||
|
||||
|
@ -131,7 +131,7 @@ describe('context app', function () {
|
|||
[]
|
||||
)
|
||||
.then((hits) => {
|
||||
const intervals = searchSourceStub.set.args
|
||||
const intervals = searchSourceStub.setField.args
|
||||
.filter(([property]) => property === 'query')
|
||||
.map(([, { query }]) => _.get(query, ['constant_score', 'filter', 'range', '@timestamp']));
|
||||
|
||||
|
@ -177,9 +177,9 @@ describe('context app', function () {
|
|||
[]
|
||||
)
|
||||
.then(() => {
|
||||
const inheritsSpy = searchSourceStub.inherits;
|
||||
expect(inheritsSpy.alwaysCalledWith(false)).to.be(true);
|
||||
expect(inheritsSpy.called).to.be(true);
|
||||
const setParentSpy = searchSourceStub.setParent;
|
||||
expect(setParentSpy.alwaysCalledWith(false)).to.be(true);
|
||||
expect(setParentSpy.called).to.be(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -95,7 +95,7 @@ describe('context app', function () {
|
|||
[]
|
||||
)
|
||||
.then((hits) => {
|
||||
const intervals = searchSourceStub.set.args
|
||||
const intervals = searchSourceStub.setField.args
|
||||
.filter(([property]) => property === 'query')
|
||||
.map(([, { query }]) => _.get(query, ['constant_score', 'filter', 'range', '@timestamp']));
|
||||
|
||||
|
@ -133,7 +133,7 @@ describe('context app', function () {
|
|||
[]
|
||||
)
|
||||
.then((hits) => {
|
||||
const intervals = searchSourceStub.set.args
|
||||
const intervals = searchSourceStub.setField.args
|
||||
.filter(([property]) => property === 'query')
|
||||
.map(([, { query }]) => _.get(query, ['constant_score', 'filter', 'range', '@timestamp']));
|
||||
|
||||
|
@ -179,9 +179,9 @@ describe('context app', function () {
|
|||
[]
|
||||
)
|
||||
.then(() => {
|
||||
const inheritsSpy = searchSourceStub.inherits;
|
||||
expect(inheritsSpy.alwaysCalledWith(false)).to.be(true);
|
||||
expect(inheritsSpy.called).to.be(true);
|
||||
const setParentSpy = searchSourceStub.setParent;
|
||||
expect(setParentSpy.alwaysCalledWith(false)).to.be(true);
|
||||
expect(setParentSpy.called).to.be(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -32,11 +32,11 @@ export function fetchAnchorProvider(indexPatterns, Private) {
|
|||
) {
|
||||
const indexPattern = await indexPatterns.get(indexPatternId);
|
||||
const searchSource = new SearchSource()
|
||||
.inherits(false)
|
||||
.set('index', indexPattern)
|
||||
.set('version', true)
|
||||
.set('size', 1)
|
||||
.set('query', {
|
||||
.setParent(false)
|
||||
.setField('index', indexPattern)
|
||||
.setField('version', true)
|
||||
.setField('size', 1)
|
||||
.setField('query', {
|
||||
query: {
|
||||
constant_score: {
|
||||
filter: {
|
||||
|
@ -49,7 +49,7 @@ export function fetchAnchorProvider(indexPatterns, Private) {
|
|||
},
|
||||
language: 'lucene',
|
||||
})
|
||||
.set('sort', sort);
|
||||
.setField('sort', sort);
|
||||
|
||||
const response = await searchSource.fetch();
|
||||
|
||||
|
|
|
@ -33,8 +33,8 @@ import { reverseSortDirection } from './utils/sorting';
|
|||
/**
|
||||
* @typedef {Object} SearchSourceT
|
||||
* @prop {function(): Promise<SearchResult>} fetch
|
||||
* @prop {function(string, any): SearchSourceT} set
|
||||
* @prop {function(any): SearchSourceT} inherits
|
||||
* @prop {function(string, any): SearchSourceT} setField
|
||||
* @prop {function(any): SearchSourceT} setParent
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -162,9 +162,9 @@ function fetchContextProvider(indexPatterns, Private) {
|
|||
const indexPattern = await indexPatterns.get(indexPatternId);
|
||||
|
||||
return new SearchSource()
|
||||
.inherits(false)
|
||||
.set('index', indexPattern)
|
||||
.set('filter', filters);
|
||||
.setParent(false)
|
||||
.setField('index', indexPattern)
|
||||
.setField('filter', filters);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -209,8 +209,8 @@ function fetchContextProvider(indexPatterns, Private) {
|
|||
};
|
||||
|
||||
const response = await searchSource
|
||||
.set('size', maxCount)
|
||||
.set('query', {
|
||||
.setField('size', maxCount)
|
||||
.setField('query', {
|
||||
query: {
|
||||
constant_score: {
|
||||
filter: {
|
||||
|
@ -225,15 +225,15 @@ function fetchContextProvider(indexPatterns, Private) {
|
|||
},
|
||||
language: 'lucene'
|
||||
})
|
||||
.set('searchAfter', [
|
||||
.setField('searchAfter', [
|
||||
afterTimeValue !== null ? afterTimeValue : startTimeValue,
|
||||
tieBreakerValue,
|
||||
])
|
||||
.set('sort', [
|
||||
.setField('sort', [
|
||||
{ [timeField]: timeSortDirection },
|
||||
{ [tieBreakerField]: tieBreakerSortDirection },
|
||||
])
|
||||
.set('version', true)
|
||||
.setField('version', true)
|
||||
.fetch();
|
||||
|
||||
return response.hits ? response.hits.hits : [];
|
||||
|
|
|
@ -24,7 +24,7 @@ export function getSavedDashboardMock(config) {
|
|||
title: 'my dashboard',
|
||||
panelsJSON: '[]',
|
||||
searchSource: {
|
||||
getOwn: (param) => param
|
||||
getOwnField: (param) => param
|
||||
}
|
||||
};
|
||||
return Object.assign(defaults, config);
|
||||
|
|
|
@ -579,8 +579,8 @@ export class DashboardStateManager {
|
|||
*/
|
||||
applyFilters(query, filters) {
|
||||
this.appState.query = query;
|
||||
this.savedDashboard.searchSource.set('query', query);
|
||||
this.savedDashboard.searchSource.set('filter', filters);
|
||||
this.savedDashboard.searchSource.setField('query', query);
|
||||
this.savedDashboard.searchSource.setField('filter', filters);
|
||||
this.saveState();
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ export class FilterUtils {
|
|||
* both query filters and filter bar filters.
|
||||
*/
|
||||
static getDashboardFilters(dashboard) {
|
||||
return dashboard.searchSource.getOwn('filter');
|
||||
return dashboard.searchSource.getOwnField('filter');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -53,8 +53,8 @@ export class FilterUtils {
|
|||
* @returns {QueryFilter}
|
||||
*/
|
||||
static getQueryFilterForDashboard(dashboard) {
|
||||
if (dashboard.searchSource.getOwn('query')) {
|
||||
return dashboard.searchSource.getOwn('query');
|
||||
if (dashboard.searchSource.getOwnField('query')) {
|
||||
return dashboard.searchSource.getOwnField('query');
|
||||
}
|
||||
|
||||
const dashboardFilters = this.getDashboardFilters(dashboard);
|
||||
|
|
|
@ -196,18 +196,17 @@ function discoverController(
|
|||
$scope.searchSource = savedSearch.searchSource;
|
||||
$scope.indexPattern = resolveIndexPatternLoading();
|
||||
$scope.searchSource
|
||||
.set('index', $scope.indexPattern)
|
||||
.highlightAll(true)
|
||||
.version(true);
|
||||
.setField('index', $scope.indexPattern)
|
||||
.setField('highlightAll', true)
|
||||
.setField('version', true);
|
||||
|
||||
// searchSource which applies time range
|
||||
const timeRangeSearchSource = savedSearch.searchSource.new();
|
||||
timeRangeSearchSource.set('filter', () => {
|
||||
const timeRangeSearchSource = savedSearch.searchSource.create();
|
||||
timeRangeSearchSource.setField('filter', () => {
|
||||
return timefilter.createFilter($scope.indexPattern);
|
||||
});
|
||||
|
||||
$scope.searchSource.inherits(timeRangeSearchSource);
|
||||
|
||||
$scope.searchSource.setParent(timeRangeSearchSource);
|
||||
|
||||
const pageTitleSuffix = savedSearch.id && savedSearch.title ? `: ${savedSearch.title}` : '';
|
||||
docTitle.change(`Discover${pageTitleSuffix}`);
|
||||
|
@ -258,26 +257,26 @@ function discoverController(
|
|||
};
|
||||
|
||||
this.getSharingData = async () => {
|
||||
const searchSource = $scope.searchSource.clone();
|
||||
const searchSource = $scope.searchSource.createCopy();
|
||||
|
||||
const { searchFields, selectFields } = await getSharingDataFields();
|
||||
searchSource.set('fields', searchFields);
|
||||
searchSource.set('sort', getSort($state.sort, $scope.indexPattern));
|
||||
searchSource.set('highlight', null);
|
||||
searchSource.set('highlightAll', null);
|
||||
searchSource.set('aggs', null);
|
||||
searchSource.set('size', null);
|
||||
searchSource.setField('fields', searchFields);
|
||||
searchSource.setField('sort', getSort($state.sort, $scope.indexPattern));
|
||||
searchSource.setField('highlight', null);
|
||||
searchSource.setField('highlightAll', null);
|
||||
searchSource.setField('aggs', null);
|
||||
searchSource.setField('size', null);
|
||||
|
||||
const body = await searchSource.getSearchRequestBody();
|
||||
return {
|
||||
searchRequest: {
|
||||
index: searchSource.get('index').title,
|
||||
index: searchSource.getField('index').title,
|
||||
body
|
||||
},
|
||||
fields: selectFields,
|
||||
metaFields: $scope.indexPattern.metaFields,
|
||||
conflictedTypesFields: $scope.indexPattern.fields.filter(f => f.type === 'conflict').map(f => f.name),
|
||||
indexPatternId: searchSource.get('index').id
|
||||
indexPatternId: searchSource.getField('index').id
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -293,7 +292,7 @@ function discoverController(
|
|||
|
||||
function getStateDefaults() {
|
||||
return {
|
||||
query: $scope.searchSource.get('query') || {
|
||||
query: $scope.searchSource.getField('query') || {
|
||||
query: '',
|
||||
language: localStorage.get('kibana.userQueryLanguage') || config.get('search:queryLanguage')
|
||||
},
|
||||
|
@ -301,7 +300,7 @@ function discoverController(
|
|||
columns: savedSearch.columns.length > 0 ? savedSearch.columns : config.get('defaultColumns').slice(),
|
||||
index: $scope.indexPattern.id,
|
||||
interval: 'auto',
|
||||
filters: _.cloneDeep($scope.searchSource.getOwn('filter'))
|
||||
filters: _.cloneDeep($scope.searchSource.getOwnField('filter'))
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -344,7 +343,7 @@ function discoverController(
|
|||
if (!sort) return;
|
||||
|
||||
// get the current sort from {key: val} to ["key", "val"];
|
||||
const currentSort = _.pairs($scope.searchSource.get('sort')).pop();
|
||||
const currentSort = _.pairs($scope.searchSource.getField('sort')).pop();
|
||||
|
||||
// if the searchSource doesn't know, tell it so
|
||||
if (!angular.equals(sort, currentSort)) $scope.fetch();
|
||||
|
@ -535,7 +534,11 @@ function discoverController(
|
|||
}
|
||||
|
||||
$scope.updateTime();
|
||||
if (sort[0] === '_score') segmented.setMaxSegments(1);
|
||||
|
||||
if (sort[0] === '_score') {
|
||||
segmented.setMaxSegments(1);
|
||||
}
|
||||
|
||||
segmented.setDirection(sortBy === 'time' ? (sort[1] || 'desc') : 'desc');
|
||||
segmented.setSortFn(sortFn);
|
||||
segmented.setSize($scope.opts.sampleSize);
|
||||
|
@ -567,14 +570,14 @@ function discoverController(
|
|||
.resolve(responseHandler($scope.vis, merged))
|
||||
.then(resp => {
|
||||
$scope.visData = resp;
|
||||
const visEl = $element.find('.visualization-container')[0];
|
||||
const visEl = $element.find('#discoverHistogram')[0];
|
||||
visualizationLoader(visEl, $scope.vis, $scope.visData, $scope.uiState, { listenOnChange: true });
|
||||
});
|
||||
}
|
||||
|
||||
$scope.hits = merged.hits.total;
|
||||
|
||||
const indexPattern = $scope.searchSource.get('index');
|
||||
const indexPattern = $scope.searchSource.getField('index');
|
||||
|
||||
// the merge rows, use a new array to help watchers
|
||||
$scope.rows = merged.hits.hits.slice();
|
||||
|
@ -646,10 +649,10 @@ function discoverController(
|
|||
|
||||
$scope.updateDataSource = Promise.method(function updateDataSource() {
|
||||
$scope.searchSource
|
||||
.size($scope.opts.sampleSize)
|
||||
.sort(getSort($state.sort, $scope.indexPattern))
|
||||
.query(!$state.query ? null : $state.query)
|
||||
.set('filter', queryFilter.getFilters());
|
||||
.setField('size', $scope.opts.sampleSize)
|
||||
.setField('sort', getSort($state.sort, $scope.indexPattern))
|
||||
.setField('query', !$state.query ? null : $state.query)
|
||||
.setField('filter', queryFilter.getFilters());
|
||||
});
|
||||
|
||||
$scope.setSortOrder = function setSortOrder(columnName, direction) {
|
||||
|
@ -731,7 +734,7 @@ function discoverController(
|
|||
return $scope.vis.getAggConfig().onSearchRequestStart(searchSource, searchRequest);
|
||||
});
|
||||
|
||||
$scope.searchSource.aggs(function () {
|
||||
$scope.searchSource.setField('aggs', function () {
|
||||
return $scope.vis.getAggConfig().toDsl();
|
||||
});
|
||||
}
|
||||
|
@ -747,7 +750,7 @@ function discoverController(
|
|||
const stateVal = props.stateVal;
|
||||
const stateValFound = props.stateValFound;
|
||||
|
||||
const own = $scope.searchSource.getOwn('index');
|
||||
const own = $scope.searchSource.getOwnField('index');
|
||||
|
||||
if (own && !stateVal) return own;
|
||||
if (stateVal && !stateValFound) {
|
||||
|
|
|
@ -29,7 +29,7 @@ export class SearchEmbeddable extends Embeddable {
|
|||
metadata: {
|
||||
title: savedSearch.title,
|
||||
editUrl,
|
||||
indexPattern: savedSearch.searchSource.get('index')
|
||||
indexPattern: savedSearch.searchSource.getField('index')
|
||||
}
|
||||
});
|
||||
this.onEmbeddableStateChanged = onEmbeddableStateChanged;
|
||||
|
@ -58,8 +58,8 @@ export class SearchEmbeddable extends Embeddable {
|
|||
this.searchScope.sort = this.customization.sort || this.savedSearch.sort;
|
||||
this.searchScope.sharedItemTitle = this.panelTitle;
|
||||
|
||||
this.filtersSearchSource.set('filter', this.filters);
|
||||
this.filtersSearchSource.set('query', this.query);
|
||||
this.filtersSearchSource.setField('filter', this.filters);
|
||||
this.filtersSearchSource.setField('query', this.query);
|
||||
}
|
||||
|
||||
onContainerStateChanged(containerState) {
|
||||
|
@ -85,15 +85,15 @@ export class SearchEmbeddable extends Embeddable {
|
|||
this.searchScope.description = this.savedSearch.description;
|
||||
this.searchScope.searchSource = this.savedSearch.searchSource;
|
||||
|
||||
const timeRangeSearchSource = this.searchScope.searchSource.new();
|
||||
timeRangeSearchSource.filter(() => {
|
||||
return getTime(this.searchScope.searchSource.get('index'), this.timeRange);
|
||||
const timeRangeSearchSource = this.searchScope.searchSource.create();
|
||||
timeRangeSearchSource.setField('filter', () => {
|
||||
return getTime(this.searchScope.searchSource.getField('index'), this.timeRange);
|
||||
});
|
||||
|
||||
this.filtersSearchSource = this.searchScope.searchSource.new();
|
||||
this.filtersSearchSource.inherits(timeRangeSearchSource);
|
||||
this.filtersSearchSource = this.searchScope.searchSource.create();
|
||||
this.filtersSearchSource.setParent(timeRangeSearchSource);
|
||||
|
||||
this.searchScope.searchSource.inherits(this.filtersSearchSource);
|
||||
this.searchScope.searchSource.setParent(this.filtersSearchSource);
|
||||
|
||||
this.pushContainerStateParamsToScope();
|
||||
|
||||
|
@ -103,14 +103,14 @@ export class SearchEmbeddable extends Embeddable {
|
|||
};
|
||||
|
||||
this.searchScope.addColumn = (columnName) => {
|
||||
this.savedSearch.searchSource.get('index').popularizeField(columnName, 1);
|
||||
this.savedSearch.searchSource.getField('index').popularizeField(columnName, 1);
|
||||
columnActions.addColumn(this.searchScope.columns, columnName);
|
||||
this.searchScope.columns = this.customization.columns = this.searchScope.columns;
|
||||
this.emitEmbeddableStateChange(this.getEmbeddableState());
|
||||
};
|
||||
|
||||
this.searchScope.removeColumn = (columnName) => {
|
||||
this.savedSearch.searchSource.get('index').popularizeField(columnName, 1);
|
||||
this.savedSearch.searchSource.getField('index').popularizeField(columnName, 1);
|
||||
columnActions.removeColumn(this.searchScope.columns, columnName);
|
||||
this.customization.columns = this.searchScope.columns;
|
||||
this.emitEmbeddableStateChange(this.getEmbeddableState());
|
||||
|
@ -123,7 +123,7 @@ export class SearchEmbeddable extends Embeddable {
|
|||
};
|
||||
|
||||
this.searchScope.filter = (field, value, operator) => {
|
||||
const index = this.savedSearch.searchSource.get('index').id;
|
||||
const index = this.savedSearch.searchSource.getField('index').id;
|
||||
const stagedFilter = {
|
||||
field,
|
||||
value,
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
columns="state.columns"
|
||||
hits="rows"
|
||||
field-counts="fieldCounts"
|
||||
index-pattern="searchSource.get('index')"
|
||||
index-pattern="searchSource.getField('index')"
|
||||
index-pattern-list="opts.indexPatternList"
|
||||
state="state"
|
||||
on-add-field="addColumn"
|
||||
|
@ -129,7 +129,7 @@
|
|||
|
||||
</header>
|
||||
|
||||
<div class="visualization-container"
|
||||
<div id="discoverHistogram"
|
||||
ng-if="vis && rows.length !== 0"
|
||||
style="display: flex; height: 200px"
|
||||
>
|
||||
|
|
|
@ -163,7 +163,7 @@ describe('Flyout', () => {
|
|||
},
|
||||
obj: {
|
||||
searchSource: {
|
||||
getOwn: () => 'MyIndexPattern*',
|
||||
getOwnField: () => 'MyIndexPattern*',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -144,7 +144,7 @@ export class Flyout extends Component {
|
|||
);
|
||||
|
||||
const byId = groupBy(conflictedIndexPatterns, ({ obj }) =>
|
||||
obj.searchSource.getOwn('index')
|
||||
obj.searchSource.getOwnField('index')
|
||||
);
|
||||
const conflicts = Object.entries(byId).reduce(
|
||||
(accum, [existingIndexPatternId, list]) => {
|
||||
|
|
|
@ -238,7 +238,7 @@ describe('resolveSavedObjects', () => {
|
|||
{
|
||||
obj: {
|
||||
searchSource: {
|
||||
getOwn: () => '1',
|
||||
getOwnField: () => '1',
|
||||
},
|
||||
hydrateIndexPattern,
|
||||
save,
|
||||
|
@ -247,7 +247,7 @@ describe('resolveSavedObjects', () => {
|
|||
{
|
||||
obj: {
|
||||
searchSource: {
|
||||
getOwn: () => '3',
|
||||
getOwnField: () => '3',
|
||||
},
|
||||
hydrateIndexPattern,
|
||||
save,
|
||||
|
|
|
@ -81,7 +81,7 @@ export async function resolveIndexPatternConflicts(
|
|||
) {
|
||||
let importCount = 0;
|
||||
await awaitEachItemInParallel(conflictedIndexPatterns, async ({ obj }) => {
|
||||
let oldIndexId = obj.searchSource.getOwn('index');
|
||||
let oldIndexId = obj.searchSource.getOwnField('index');
|
||||
// Depending on the object, this can either be the raw id or the actual index pattern object
|
||||
if (typeof oldIndexId !== 'string') {
|
||||
oldIndexId = oldIndexId.id;
|
||||
|
|
|
@ -191,11 +191,11 @@ function VisEditor(
|
|||
const stateDefaults = {
|
||||
uiState: savedVis.uiStateJSON ? JSON.parse(savedVis.uiStateJSON) : {},
|
||||
linked: !!savedVis.savedSearchId,
|
||||
query: searchSource.getOwn('query') || {
|
||||
query: searchSource.getOwnField('query') || {
|
||||
query: '',
|
||||
language: localStorage.get('kibana.userQueryLanguage') || config.get('search:queryLanguage')
|
||||
},
|
||||
filters: searchSource.getOwn('filter') || [],
|
||||
filters: searchSource.getOwnField('filter') || [],
|
||||
vis: savedVisState
|
||||
};
|
||||
|
||||
|
@ -252,7 +252,7 @@ function VisEditor(
|
|||
};
|
||||
|
||||
$scope.$watchMulti([
|
||||
'searchSource.get("index")',
|
||||
'searchSource.getField("index")',
|
||||
'vis.type.options.showTimePicker',
|
||||
], function ([index, requiresTimePicker]) {
|
||||
const showTimeFilter = Boolean((!index || index.timeFieldName) && requiresTimePicker);
|
||||
|
@ -279,8 +279,8 @@ function VisEditor(
|
|||
// update the searchSource when query updates
|
||||
$scope.fetch = function () {
|
||||
$state.save();
|
||||
savedVis.searchSource.set('query', $state.query);
|
||||
savedVis.searchSource.set('filter', $state.filters);
|
||||
savedVis.searchSource.setField('query', $state.query);
|
||||
savedVis.searchSource.setField('filter', $state.filters);
|
||||
$scope.vis.forceReload();
|
||||
};
|
||||
|
||||
|
@ -348,23 +348,23 @@ function VisEditor(
|
|||
toastNotifications.addSuccess(`Unlinked from saved search '${savedVis.savedSearch.title}'`);
|
||||
|
||||
$state.linked = false;
|
||||
const parent = searchSource.getParent(true);
|
||||
const parentsParent = parent.getParent(true);
|
||||
const searchSourceParent = searchSource.getParent(true);
|
||||
const searchSourceGrandparent = searchSourceParent.getParent(true);
|
||||
|
||||
delete savedVis.savedSearchId;
|
||||
parent.set('filter', _.union(searchSource.getOwn('filter'), parent.getOwn('filter')));
|
||||
searchSourceParent.setField('filter', _.union(searchSource.getOwnField('filter'), searchSourceParent.getOwnField('filter')));
|
||||
|
||||
// copy over all state except "aggs", "query" and "filter"
|
||||
_(parent.toJSON())
|
||||
_(searchSourceParent.toJSON())
|
||||
.omit(['aggs', 'filter', 'query'])
|
||||
.forOwn(function (val, key) {
|
||||
searchSource.set(key, val);
|
||||
searchSource.setField(key, val);
|
||||
})
|
||||
.commit();
|
||||
|
||||
$state.query = searchSource.get('query');
|
||||
$state.filters = searchSource.get('filter');
|
||||
searchSource.inherits(parentsParent);
|
||||
$state.query = searchSource.getField('query');
|
||||
$state.filters = searchSource.getField('filter');
|
||||
searchSource.setParent(searchSourceGrandparent);
|
||||
|
||||
$scope.fetch();
|
||||
};
|
||||
|
|
|
@ -95,7 +95,7 @@ uiModules
|
|||
|
||||
return self._getLinkedSavedSearch()
|
||||
.then(function () {
|
||||
self.searchSource.size(0);
|
||||
self.searchSource.setField('size', 0);
|
||||
|
||||
return self.vis ? self._updateVis() : self._createVis();
|
||||
});
|
||||
|
@ -111,7 +111,7 @@ uiModules
|
|||
}
|
||||
|
||||
if (self.savedSearch) {
|
||||
self.searchSource.inherits(self.savedSearch.searchSource.getParent());
|
||||
self.searchSource.setParent(self.savedSearch.searchSource.getParent());
|
||||
self.savedSearch.destroy();
|
||||
self.savedSearch = null;
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ uiModules
|
|||
return savedSearches.get(self.savedSearchId)
|
||||
.then(function (savedSearch) {
|
||||
self.savedSearch = savedSearch;
|
||||
self.searchSource.inherits(self.savedSearch.searchSource);
|
||||
self.searchSource.setParent(self.savedSearch.searchSource);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -137,7 +137,7 @@ uiModules
|
|||
self.visState.title = self.title;
|
||||
}
|
||||
self.vis = new Vis(
|
||||
self.searchSource.get('index'),
|
||||
self.searchSource.getField('index'),
|
||||
self.visState
|
||||
);
|
||||
|
||||
|
@ -147,7 +147,7 @@ uiModules
|
|||
SavedVis.prototype._updateVis = function () {
|
||||
const self = this;
|
||||
|
||||
self.vis.indexPattern = self.searchSource.get('index');
|
||||
self.vis.indexPattern = self.searchSource.getField('index');
|
||||
self.visState.title = self.title;
|
||||
self.vis.setState(self.visState);
|
||||
};
|
||||
|
|
|
@ -22,15 +22,15 @@ export async function collectIndexPatterns(savedObjectsClient, panels) {
|
|||
const { kibanaSavedObjectMeta, savedSearchId } = panel.attributes;
|
||||
|
||||
if (kibanaSavedObjectMeta && kibanaSavedObjectMeta.searchSourceJSON && !savedSearchId) {
|
||||
let searchSource;
|
||||
let searchSourceData;
|
||||
try {
|
||||
searchSource = JSON.parse(kibanaSavedObjectMeta.searchSourceJSON);
|
||||
searchSourceData = JSON.parse(kibanaSavedObjectMeta.searchSourceJSON);
|
||||
} catch (err) {
|
||||
return acc;
|
||||
}
|
||||
|
||||
if (searchSource.index && !acc.find(s => s.id === searchSource.index)) {
|
||||
acc.push({ type: 'index-pattern', id: searchSource.index });
|
||||
if (searchSourceData.index && !acc.find(s => s.id === searchSourceData.index)) {
|
||||
acc.push({ type: 'index-pattern', id: searchSourceData.index });
|
||||
}
|
||||
}
|
||||
return acc;
|
||||
|
|
|
@ -185,9 +185,9 @@ export function CoordinateMapsVisualizationProvider(Notifier, Private) {
|
|||
async getGeohashBounds() {
|
||||
const agg = this._getGeoHashAgg();
|
||||
if (agg) {
|
||||
const searchSource = this.vis.searchSource.makeChild();
|
||||
searchSource.size(0);
|
||||
searchSource.aggs(function () {
|
||||
const searchSource = this.vis.searchSource.createChild();
|
||||
searchSource.setField('size', 0);
|
||||
searchSource.setField('aggs', function () {
|
||||
const geoBoundsAgg = new AggConfig(agg.vis, {
|
||||
type: 'geo_bounds',
|
||||
enabled: true,
|
||||
|
|
|
@ -27,16 +27,15 @@ export default function stubSearchSource(Private, $q, Promise) {
|
|||
|
||||
let onResultsCount = 0;
|
||||
return {
|
||||
sort: sinon.spy(),
|
||||
size: sinon.spy(),
|
||||
setField: sinon.spy(),
|
||||
fetch: sinon.spy(),
|
||||
destroy: sinon.spy(),
|
||||
get: function (param) {
|
||||
getField: function (param) {
|
||||
switch (param) {
|
||||
case 'index':
|
||||
return indexPattern;
|
||||
default:
|
||||
throw new Error('Param "' + param + '" is not implemented in the stubbed search source');
|
||||
throw new Error(`Param "${param}" is not implemented in the stubbed search source`);
|
||||
}
|
||||
},
|
||||
crankResults: function () {
|
||||
|
|
|
@ -70,9 +70,9 @@ export const histogramBucketAgg = new BucketAggType({
|
|||
: { field: field.name };
|
||||
|
||||
return searchSource
|
||||
.extend()
|
||||
.size(0)
|
||||
.aggs({
|
||||
.createChild()
|
||||
.setField('size', 0)
|
||||
.setField('aggs', {
|
||||
maxAgg: {
|
||||
max: aggBody
|
||||
},
|
||||
|
|
|
@ -93,10 +93,10 @@ export const termsBucketAgg = new BucketAggType({
|
|||
},
|
||||
createFilter: createFilterTerms,
|
||||
postFlightRequest: async (resp, aggConfigs, aggConfig, searchSource) => {
|
||||
const nestedSearchSource = searchSource.makeChild();
|
||||
const nestedSearchSource = searchSource.createChild();
|
||||
if (aggConfig.params.otherBucket) {
|
||||
const filterAgg = buildOtherBucketAgg(aggConfigs, aggConfig, resp);
|
||||
nestedSearchSource.set('aggs', filterAgg);
|
||||
nestedSearchSource.setField('aggs', filterAgg);
|
||||
|
||||
const request = aggConfigs.vis.API.inspectorAdapters.requests.start('Other bucket', {
|
||||
description: `This request counts the number of documents that fall
|
||||
|
|
|
@ -30,16 +30,16 @@ export function MergeDuplicatesRequestProvider(Private) {
|
|||
return requests.map(function (req) {
|
||||
if (!isRequest(req)) return req;
|
||||
|
||||
const iid = req.source._instanceid;
|
||||
if (!index[iid]) {
|
||||
const searchSourceId = req.source.getId();
|
||||
if (!index[searchSourceId]) {
|
||||
// this request is unique so far
|
||||
index[iid] = req;
|
||||
index[searchSourceId] = req;
|
||||
// keep the request
|
||||
return req;
|
||||
}
|
||||
|
||||
// the source was requested at least twice
|
||||
req._uniq = index[iid];
|
||||
req._uniq = index[searchSourceId];
|
||||
return DUPLICATE;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -55,28 +55,28 @@ describe('SegmentedSearchRequest _createQueue', () => {
|
|||
});
|
||||
|
||||
it('relies on indexPattern.toDetailedIndexList to generate queue', async function () {
|
||||
const source = new MockSource();
|
||||
const ip = source.get('index');
|
||||
const searchSource = new MockSource();
|
||||
const indexPattern = searchSource.getField('index');
|
||||
const indices = [1, 2, 3];
|
||||
sinon.stub(ip, 'toDetailedIndexList').returns(Promise.resolve(indices));
|
||||
sinon.stub(indexPattern, 'toDetailedIndexList').returns(Promise.resolve(indices));
|
||||
|
||||
const req = new SegmentedSearchRequest({ source, errorHandler: () => {} });
|
||||
const req = new SegmentedSearchRequest({ source: searchSource, errorHandler: () => {} });
|
||||
const output = await req._createQueue();
|
||||
expect(output).to.equal(indices);
|
||||
});
|
||||
|
||||
it('tells the index pattern its direction', async function () {
|
||||
const source = new MockSource();
|
||||
const ip = source.get('index');
|
||||
const req = new SegmentedSearchRequest({ source, errorHandler: () => {} });
|
||||
sinon.stub(ip, 'toDetailedIndexList').returns(Promise.resolve([1, 2, 3]));
|
||||
const searchSource = new MockSource();
|
||||
const indexPattern = searchSource.getField('index');
|
||||
const req = new SegmentedSearchRequest({ source: searchSource, errorHandler: () => {} });
|
||||
sinon.stub(indexPattern, 'toDetailedIndexList').returns(Promise.resolve([1, 2, 3]));
|
||||
|
||||
req.setDirection('asc');
|
||||
await req._createQueue();
|
||||
expect(ip.toDetailedIndexList.lastCall.args[2]).to.be('asc');
|
||||
expect(indexPattern.toDetailedIndexList.lastCall.args[2]).to.be('asc');
|
||||
|
||||
req.setDirection('desc');
|
||||
await req._createQueue();
|
||||
expect(ip.toDetailedIndexList.lastCall.args[2]).to.be('desc');
|
||||
expect(indexPattern.toDetailedIndexList.lastCall.args[2]).to.be('desc');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -50,8 +50,8 @@ describe('SegmentedSearchRequest index selection', function () {
|
|||
}));
|
||||
|
||||
it('queries with size until all 500 docs returned', async function () {
|
||||
const search = new MockSource();
|
||||
const indexPattern = search.get('index');
|
||||
const searchSource = new MockSource();
|
||||
const indexPattern = searchSource.getField('index');
|
||||
sinon.stub(indexPattern, 'toDetailedIndexList').returns(Promise.resolve([
|
||||
{ index: 'one', min: 0, max: 1 },
|
||||
{ index: 'two', min: 0, max: 1 },
|
||||
|
@ -60,7 +60,7 @@ describe('SegmentedSearchRequest index selection', function () {
|
|||
{ index: 'five', min: 0, max: 1 },
|
||||
]));
|
||||
|
||||
const req = new SegmentedSearchRequest({ source: search, errorHandler: () => {} });
|
||||
const req = new SegmentedSearchRequest({ source: searchSource, errorHandler: () => {} });
|
||||
req._handle.setDirection('desc');
|
||||
req._handle.setSortFn(new HitSortFn('desc'));
|
||||
req._handle.setSize(500);
|
||||
|
@ -96,8 +96,8 @@ describe('SegmentedSearchRequest index selection', function () {
|
|||
});
|
||||
|
||||
it(`sets size 0 for indices that couldn't preclude hits`, async function () {
|
||||
const search = new MockSource();
|
||||
const indexPattern = search.get('index');
|
||||
const searchSource = new MockSource();
|
||||
const indexPattern = searchSource.getField('index');
|
||||
|
||||
// the segreq is looking for 10 documents, and we will give it ten docs with time:5 in the first response.
|
||||
// on the second index it should still request 10 documents because it could produce documents with time:5.
|
||||
|
@ -111,7 +111,7 @@ describe('SegmentedSearchRequest index selection', function () {
|
|||
{ index: 'five', min: 5, max: 50 },
|
||||
]));
|
||||
|
||||
const req = new SegmentedSearchRequest({ source: search, errorHandler: () => {} });
|
||||
const req = new SegmentedSearchRequest({ source: searchSource, errorHandler: () => {} });
|
||||
req._handle.setDirection('desc');
|
||||
req._handle.setSortFn(new HitSortFn('desc'));
|
||||
req._handle.setSize(10);
|
||||
|
|
|
@ -195,7 +195,7 @@ export function SegmentedSearchRequestProvider(Private, config) {
|
|||
|
||||
_createQueue() {
|
||||
const timeBounds = timefilter.getBounds();
|
||||
const indexPattern = this.source.get('index');
|
||||
const indexPattern = this.source.getField('index');
|
||||
this._queueCreated = false;
|
||||
|
||||
return indexPattern.toDetailedIndexList(timeBounds.min, timeBounds.max, this._direction)
|
||||
|
@ -298,7 +298,7 @@ export function SegmentedSearchRequestProvider(Private, config) {
|
|||
|
||||
_detectHitsWindow(hits) {
|
||||
hits = hits || [];
|
||||
const indexPattern = this.source.get('index');
|
||||
const indexPattern = this.source.getField('index');
|
||||
const desiredSize = this._desiredSize;
|
||||
|
||||
const size = _.size(hits);
|
||||
|
|
|
@ -432,11 +432,11 @@ describe('Saved Object', function () {
|
|||
});
|
||||
|
||||
const savedObject = new SavedObject(config);
|
||||
expect(!!savedObject.searchSource.get('index')).to.be(false);
|
||||
expect(!!savedObject.searchSource.getField('index')).to.be(false);
|
||||
|
||||
return savedObject.init().then(() => {
|
||||
expect(afterESRespCallback.called).to.be(true);
|
||||
const index = savedObject.searchSource.get('index');
|
||||
const index = savedObject.searchSource.getField('index');
|
||||
expect(index instanceof IndexPattern).to.be(true);
|
||||
expect(index.id).to.equal(indexPatternId);
|
||||
});
|
||||
|
|
|
@ -112,23 +112,23 @@ export function SavedObjectProvider(Promise, Private, Notifier, confirmModalProm
|
|||
const parseSearchSource = (searchSourceJson) => {
|
||||
if (!this.searchSource) return;
|
||||
|
||||
// if we have a searchSource, set its state based on the searchSourceJSON field
|
||||
let state;
|
||||
// if we have a searchSource, set its values based on the searchSourceJson field
|
||||
let searchSourceValues;
|
||||
try {
|
||||
state = JSON.parse(searchSourceJson);
|
||||
searchSourceValues = JSON.parse(searchSourceJson);
|
||||
} catch (e) {
|
||||
state = {};
|
||||
searchSourceValues = {};
|
||||
}
|
||||
|
||||
const oldState = this.searchSource.toJSON();
|
||||
const fnProps = _.transform(oldState, function (dynamic, val, name) {
|
||||
const searchSourceFields = this.searchSource.getFields();
|
||||
const fnProps = _.transform(searchSourceFields, function (dynamic, val, name) {
|
||||
if (_.isFunction(val)) dynamic[name] = val;
|
||||
}, {});
|
||||
|
||||
this.searchSource.set(_.defaults(state, fnProps));
|
||||
this.searchSource.setFields(_.defaults(searchSourceValues, fnProps));
|
||||
|
||||
if (!_.isUndefined(this.searchSource.getOwn('query'))) {
|
||||
this.searchSource.set('query', migrateLegacyQuery(this.searchSource.getOwn('query')));
|
||||
if (!_.isUndefined(this.searchSource.getOwnField('query'))) {
|
||||
this.searchSource.setField('query', migrateLegacyQuery(this.searchSource.getOwnField('query')));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -144,11 +144,11 @@ export function SavedObjectProvider(Promise, Private, Notifier, confirmModalProm
|
|||
}
|
||||
|
||||
if (config.clearSavedIndexPattern) {
|
||||
this.searchSource.set('index', undefined);
|
||||
this.searchSource.setField('index', null);
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
let index = id || config.indexPattern || this.searchSource.getOwn('index');
|
||||
let index = id || config.indexPattern || this.searchSource.getOwnField('index');
|
||||
|
||||
if (!index) {
|
||||
return Promise.resolve(null);
|
||||
|
@ -162,7 +162,7 @@ export function SavedObjectProvider(Promise, Private, Notifier, confirmModalProm
|
|||
// At this point index will either be an IndexPattern, if cached, or a promise that
|
||||
// will return an IndexPattern, if not cached.
|
||||
return Promise.resolve(index).then(indexPattern => {
|
||||
this.searchSource.set('index', indexPattern);
|
||||
this.searchSource.setField('index', indexPattern);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -260,8 +260,9 @@ export function SavedObjectProvider(Promise, Private, Notifier, confirmModalProm
|
|||
});
|
||||
|
||||
if (this.searchSource) {
|
||||
const searchSourceFields = _.omit(this.searchSource.getFields(), ['sort', 'size']);
|
||||
body.kibanaSavedObjectMeta = {
|
||||
searchSourceJSON: angular.toJson(_.omit(this.searchSource.toJSON(), ['sort', 'size']))
|
||||
searchSourceJSON: angular.toJson(searchSourceFields)
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -54,18 +54,18 @@ describe('SearchSource', function () {
|
|||
|
||||
describe('#onResults()', function () {
|
||||
it('adds a request to the searchRequestQueue', function () {
|
||||
const source = new SearchSource();
|
||||
const searchSource = new SearchSource();
|
||||
|
||||
expect(searchRequestQueue.getCount()).to.be(0);
|
||||
source.onResults();
|
||||
searchSource.onResults();
|
||||
expect(searchRequestQueue.getCount()).to.be(1);
|
||||
});
|
||||
|
||||
it('returns a promise that is resolved with the results', function () {
|
||||
const source = new SearchSource();
|
||||
const searchSource = new SearchSource();
|
||||
const fakeResults = {};
|
||||
|
||||
const promise = source.onResults().then((results) => {
|
||||
const promise = searchSource.onResults().then((results) => {
|
||||
expect(results).to.be(fakeResults);
|
||||
});
|
||||
|
||||
|
@ -77,106 +77,132 @@ describe('SearchSource', function () {
|
|||
|
||||
describe('#destroy()', function () {
|
||||
it('aborts all startable requests', function () {
|
||||
const source = new SearchSource();
|
||||
source.onResults();
|
||||
const searchSource = new SearchSource();
|
||||
searchSource.onResults();
|
||||
const searchRequest = searchRequestQueue.getSearchRequestAt(0);
|
||||
sinon.stub(searchRequest, 'canStart').returns(true);
|
||||
source.destroy();
|
||||
searchSource.destroy();
|
||||
expect(searchRequestQueue.getCount()).to.be(0);
|
||||
});
|
||||
|
||||
it('aborts all non-startable requests', function () {
|
||||
const source = new SearchSource();
|
||||
source.onResults();
|
||||
const searchSource = new SearchSource();
|
||||
searchSource.onResults();
|
||||
const searchRequest = searchRequestQueue.getSearchRequestAt(0);
|
||||
sinon.stub(searchRequest, 'canStart').returns(false);
|
||||
source.destroy();
|
||||
searchSource.destroy();
|
||||
expect(searchRequestQueue.getCount()).to.be(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#index()', function () {
|
||||
describe('#setField()', function () {
|
||||
it('sets the value for the property', function () {
|
||||
const searchSource = new SearchSource();
|
||||
searchSource.setField('aggs', 5);
|
||||
expect(searchSource.getField('aggs')).to.be(5);
|
||||
});
|
||||
|
||||
it('throws an error if the property is not accepted', function () {
|
||||
const searchSource = new SearchSource();
|
||||
expect(() => searchSource.setField('index', 5)).to.throwError();
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getField()', function () {
|
||||
it('gets the value for the property', function () {
|
||||
const searchSource = new SearchSource();
|
||||
searchSource.setField('aggs', 5);
|
||||
expect(searchSource.getField('aggs')).to.be(5);
|
||||
});
|
||||
|
||||
it('throws an error if the property is not accepted', function () {
|
||||
const searchSource = new SearchSource();
|
||||
expect(() => searchSource.getField('unacceptablePropName')).to.throwError();
|
||||
});
|
||||
});
|
||||
|
||||
describe(`#setField('index')`, function () {
|
||||
describe('auto-sourceFiltering', function () {
|
||||
describe('new index pattern assigned', function () {
|
||||
it('generates a source filter', function () {
|
||||
const source = new SearchSource();
|
||||
expect(source.get('index')).to.be(undefined);
|
||||
expect(source.get('source')).to.be(undefined);
|
||||
source.set('index', indexPattern);
|
||||
expect(source.get('index')).to.be(indexPattern);
|
||||
expect(source.get('source')).to.be.a('function');
|
||||
it('generates a searchSource filter', function () {
|
||||
const searchSource = new SearchSource();
|
||||
expect(searchSource.getField('index')).to.be(undefined);
|
||||
expect(searchSource.getField('source')).to.be(undefined);
|
||||
searchSource.setField('index', indexPattern);
|
||||
expect(searchSource.getField('index')).to.be(indexPattern);
|
||||
expect(searchSource.getField('source')).to.be.a('function');
|
||||
});
|
||||
|
||||
it('removes created source filter on removal', function () {
|
||||
const source = new SearchSource();
|
||||
source.set('index', indexPattern);
|
||||
source.set('index', null);
|
||||
expect(source.get('index')).to.be(undefined);
|
||||
expect(source.get('source')).to.be(undefined);
|
||||
it('removes created searchSource filter on removal', function () {
|
||||
const searchSource = new SearchSource();
|
||||
searchSource.setField('index', indexPattern);
|
||||
searchSource.setField('index', null);
|
||||
expect(searchSource.getField('index')).to.be(undefined);
|
||||
expect(searchSource.getField('source')).to.be(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
describe('new index pattern assigned over another', function () {
|
||||
it('replaces source filter with new', function () {
|
||||
const source = new SearchSource();
|
||||
source.set('index', indexPattern);
|
||||
const sourceFilter1 = source.get('source');
|
||||
source.set('index', indexPattern2);
|
||||
expect(source.get('index')).to.be(indexPattern2);
|
||||
expect(source.get('source')).to.be.a('function');
|
||||
expect(source.get('source')).to.not.be(sourceFilter1);
|
||||
it('replaces searchSource filter with new', function () {
|
||||
const searchSource = new SearchSource();
|
||||
searchSource.setField('index', indexPattern);
|
||||
const searchSourceFilter1 = searchSource.getField('source');
|
||||
searchSource.setField('index', indexPattern2);
|
||||
expect(searchSource.getField('index')).to.be(indexPattern2);
|
||||
expect(searchSource.getField('source')).to.be.a('function');
|
||||
expect(searchSource.getField('source')).to.not.be(searchSourceFilter1);
|
||||
});
|
||||
|
||||
it('removes created source filter on removal', function () {
|
||||
const source = new SearchSource();
|
||||
source.set('index', indexPattern);
|
||||
source.set('index', indexPattern2);
|
||||
source.set('index', null);
|
||||
expect(source.get('index')).to.be(undefined);
|
||||
expect(source.get('source')).to.be(undefined);
|
||||
it('removes created searchSource filter on removal', function () {
|
||||
const searchSource = new SearchSource();
|
||||
searchSource.setField('index', indexPattern);
|
||||
searchSource.setField('index', indexPattern2);
|
||||
searchSource.setField('index', null);
|
||||
expect(searchSource.getField('index')).to.be(undefined);
|
||||
expect(searchSource.getField('source')).to.be(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
describe('ip assigned before custom source filter', function () {
|
||||
it('custom source filter becomes new source', function () {
|
||||
const source = new SearchSource();
|
||||
describe('ip assigned before custom searchSource filter', function () {
|
||||
it('custom searchSource filter becomes new searchSource', function () {
|
||||
const searchSource = new SearchSource();
|
||||
const football = {};
|
||||
source.set('index', indexPattern);
|
||||
expect(source.get('source')).to.be.a('function');
|
||||
source.set('source', football);
|
||||
expect(source.get('index')).to.be(indexPattern);
|
||||
expect(source.get('source')).to.be(football);
|
||||
searchSource.setField('index', indexPattern);
|
||||
expect(searchSource.getField('source')).to.be.a('function');
|
||||
searchSource.setField('source', football);
|
||||
expect(searchSource.getField('index')).to.be(indexPattern);
|
||||
expect(searchSource.getField('source')).to.be(football);
|
||||
});
|
||||
|
||||
it('custom source stays after removal', function () {
|
||||
const source = new SearchSource();
|
||||
it('custom searchSource stays after removal', function () {
|
||||
const searchSource = new SearchSource();
|
||||
const football = {};
|
||||
source.set('index', indexPattern);
|
||||
source.set('source', football);
|
||||
source.set('index', null);
|
||||
expect(source.get('index')).to.be(undefined);
|
||||
expect(source.get('source')).to.be(football);
|
||||
searchSource.setField('index', indexPattern);
|
||||
searchSource.setField('source', football);
|
||||
searchSource.setField('index', null);
|
||||
expect(searchSource.getField('index')).to.be(undefined);
|
||||
expect(searchSource.getField('source')).to.be(football);
|
||||
});
|
||||
});
|
||||
|
||||
describe('ip assigned after custom source filter', function () {
|
||||
describe('ip assigned after custom searchSource filter', function () {
|
||||
it('leaves the custom filter in place', function () {
|
||||
const source = new SearchSource();
|
||||
const searchSource = new SearchSource();
|
||||
const football = {};
|
||||
source.set('source', football);
|
||||
source.set('index', indexPattern);
|
||||
expect(source.get('index')).to.be(indexPattern);
|
||||
expect(source.get('source')).to.be(football);
|
||||
searchSource.setField('source', football);
|
||||
searchSource.setField('index', indexPattern);
|
||||
expect(searchSource.getField('index')).to.be(indexPattern);
|
||||
expect(searchSource.getField('source')).to.be(football);
|
||||
});
|
||||
|
||||
it('custom source stays after removal', function () {
|
||||
const source = new SearchSource();
|
||||
it('custom searchSource stays after removal', function () {
|
||||
const searchSource = new SearchSource();
|
||||
const football = {};
|
||||
source.set('source', football);
|
||||
source.set('index', indexPattern);
|
||||
source.set('index', null);
|
||||
expect(source.get('index')).to.be(undefined);
|
||||
expect(source.get('source')).to.be(football);
|
||||
searchSource.setField('source', football);
|
||||
searchSource.setField('index', indexPattern);
|
||||
searchSource.setField('index', null);
|
||||
expect(searchSource.getField('index')).to.be(undefined);
|
||||
expect(searchSource.getField('source')).to.be(football);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -184,66 +210,66 @@ describe('SearchSource', function () {
|
|||
|
||||
describe('#onRequestStart()', () => {
|
||||
it('should be called when starting a request', async () => {
|
||||
const source = new SearchSource();
|
||||
const searchSource = new SearchSource();
|
||||
const fn = sinon.spy();
|
||||
source.onRequestStart(fn);
|
||||
searchSource.onRequestStart(fn);
|
||||
const request = {};
|
||||
source.requestIsStarting(request);
|
||||
searchSource.requestIsStarting(request);
|
||||
await timeout();
|
||||
expect(fn.calledWith(source, request)).to.be(true);
|
||||
expect(fn.calledWith(searchSource, request)).to.be(true);
|
||||
});
|
||||
|
||||
it('should not be called on parent searchSource', async () => {
|
||||
const parent = new SearchSource();
|
||||
const source = new SearchSource().inherits(parent);
|
||||
const searchSource = new SearchSource().setParent(parent);
|
||||
|
||||
const fn = sinon.spy();
|
||||
source.onRequestStart(fn);
|
||||
searchSource.onRequestStart(fn);
|
||||
const parentFn = sinon.spy();
|
||||
parent.onRequestStart(parentFn);
|
||||
const request = {};
|
||||
source.requestIsStarting(request);
|
||||
searchSource.requestIsStarting(request);
|
||||
await timeout();
|
||||
expect(fn.calledWith(source, request)).to.be(true);
|
||||
expect(fn.calledWith(searchSource, request)).to.be(true);
|
||||
expect(parentFn.notCalled).to.be(true);
|
||||
});
|
||||
|
||||
it('should be called on parent searchSource if callParentStartHandlers is true', async () => {
|
||||
const parent = new SearchSource();
|
||||
const source = new SearchSource().inherits(parent, { callParentStartHandlers: true });
|
||||
const searchSource = new SearchSource().setParent(parent, { callParentStartHandlers: true });
|
||||
|
||||
const fn = sinon.spy();
|
||||
source.onRequestStart(fn);
|
||||
searchSource.onRequestStart(fn);
|
||||
const parentFn = sinon.spy();
|
||||
parent.onRequestStart(parentFn);
|
||||
const request = {};
|
||||
source.requestIsStarting(request);
|
||||
searchSource.requestIsStarting(request);
|
||||
await timeout();
|
||||
expect(fn.calledWith(source, request)).to.be(true);
|
||||
expect(parentFn.calledWith(source, request)).to.be(true);
|
||||
expect(fn.calledWith(searchSource, request)).to.be(true);
|
||||
expect(parentFn.calledWith(searchSource, request)).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#_mergeProp', function () {
|
||||
describe('filter', function () {
|
||||
let source;
|
||||
let searchSource;
|
||||
let state;
|
||||
|
||||
beforeEach(function () {
|
||||
source = new SearchSource();
|
||||
searchSource = new SearchSource();
|
||||
state = {};
|
||||
});
|
||||
|
||||
[null, undefined].forEach(falsyValue => {
|
||||
it(`ignores ${falsyValue} filter`, function () {
|
||||
source._mergeProp(state, falsyValue, 'filter');
|
||||
searchSource._mergeProp(state, falsyValue, 'filter');
|
||||
expect(state.filters).to.be(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
[false, 0, '', NaN].forEach(falsyValue => {
|
||||
it(`doesn't add ${falsyValue} filter`, function () {
|
||||
source._mergeProp(state, falsyValue, 'filter');
|
||||
searchSource._mergeProp(state, falsyValue, 'filter');
|
||||
expect(state.filters).to.be.empty();
|
||||
});
|
||||
});
|
||||
|
@ -252,7 +278,7 @@ describe('SearchSource', function () {
|
|||
const filter = {
|
||||
meta: {}
|
||||
};
|
||||
source._mergeProp(state, filter, 'filter');
|
||||
searchSource._mergeProp(state, filter, 'filter');
|
||||
expect(state.filters).to.eql([filter]);
|
||||
});
|
||||
|
||||
|
@ -262,7 +288,7 @@ describe('SearchSource', function () {
|
|||
disabled: false
|
||||
}
|
||||
};
|
||||
source._mergeProp(state, filter, 'filter');
|
||||
searchSource._mergeProp(state, filter, 'filter');
|
||||
expect(state.filters).to.eql([filter]);
|
||||
});
|
||||
|
||||
|
@ -272,7 +298,7 @@ describe('SearchSource', function () {
|
|||
disabled: true
|
||||
}
|
||||
};
|
||||
source._mergeProp(state, filter, 'filter');
|
||||
searchSource._mergeProp(state, filter, 'filter');
|
||||
expect(state.filters).to.be.empty();
|
||||
});
|
||||
|
||||
|
@ -289,7 +315,7 @@ describe('SearchSource', function () {
|
|||
byName: {}
|
||||
}
|
||||
};
|
||||
source._mergeProp(state, filter, 'filter');
|
||||
searchSource._mergeProp(state, filter, 'filter');
|
||||
expect(state.filters).to.eql([ filter ]);
|
||||
});
|
||||
});
|
||||
|
@ -307,7 +333,7 @@ describe('SearchSource', function () {
|
|||
byName: {}
|
||||
}
|
||||
};
|
||||
source._mergeProp(state, filter, 'filter');
|
||||
searchSource._mergeProp(state, filter, 'filter');
|
||||
expect(state.filters).to.be.empty();
|
||||
});
|
||||
|
||||
|
@ -325,20 +351,10 @@ describe('SearchSource', function () {
|
|||
}
|
||||
}
|
||||
};
|
||||
source._mergeProp(state, filter, 'filter');
|
||||
searchSource._mergeProp(state, filter, 'filter');
|
||||
expect(state.filters).to.eql([ filter ]);
|
||||
});
|
||||
});
|
||||
|
||||
it('uses custom filter predicate', function () {
|
||||
source.addFilterPredicate(() => {
|
||||
return false;
|
||||
});
|
||||
|
||||
const filter = {};
|
||||
source._mergeProp(state, filter, 'filter');
|
||||
expect(state.filters).to.be.empty();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -84,14 +84,31 @@ import { FieldWildcardProvider } from '../../field_wildcard';
|
|||
import { getHighlightRequest } from '../../../../core_plugins/kibana/common/highlight';
|
||||
import { BuildESQueryProvider } from './build_query';
|
||||
|
||||
function parseInitialState(initialState) {
|
||||
if (!initialState) {
|
||||
const FIELDS = [
|
||||
'type',
|
||||
'query',
|
||||
'filter',
|
||||
'sort',
|
||||
'highlight',
|
||||
'highlightAll',
|
||||
'aggs',
|
||||
'from',
|
||||
'searchAfter',
|
||||
'size',
|
||||
'source',
|
||||
'version',
|
||||
'fields',
|
||||
'index',
|
||||
];
|
||||
|
||||
function parseInitialFields(initialFields) {
|
||||
if (!initialFields) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return typeof initialState === 'string' ?
|
||||
JSON.parse(initialState)
|
||||
: _.cloneDeep(initialState);
|
||||
return typeof initialFields === 'string' ?
|
||||
JSON.parse(initialFields)
|
||||
: _.cloneDeep(initialFields);
|
||||
}
|
||||
|
||||
function isIndexPattern(val) {
|
||||
|
@ -110,45 +127,11 @@ export function SearchSourceProvider(Promise, Private, config) {
|
|||
const forIp = Symbol('for which index pattern?');
|
||||
|
||||
class SearchSource {
|
||||
constructor(initialState) {
|
||||
this._instanceid = _.uniqueId('data_source');
|
||||
constructor(initialFields) {
|
||||
this._id = _.uniqueId('data_source');
|
||||
|
||||
this._state = parseInitialState(initialState);
|
||||
|
||||
/**
|
||||
* List of the editable state properties that turn into a
|
||||
* chainable API
|
||||
*
|
||||
* @type {Array}
|
||||
*/
|
||||
this._methods = [
|
||||
'type',
|
||||
'query',
|
||||
'filter',
|
||||
'sort',
|
||||
'highlight',
|
||||
'highlightAll',
|
||||
'aggs',
|
||||
'from',
|
||||
'searchAfter',
|
||||
'size',
|
||||
'source',
|
||||
'version',
|
||||
'fields'
|
||||
];
|
||||
|
||||
// set internal state values
|
||||
this._methods.forEach(name => {
|
||||
this[name] = val => {
|
||||
if (val == null) {
|
||||
delete this._state[name];
|
||||
} else {
|
||||
this._state[name] = val;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
});
|
||||
this._fields = parseInitialFields(initialFields);
|
||||
this._parent = undefined;
|
||||
|
||||
this.history = [];
|
||||
this._requestStartHandlers = [];
|
||||
|
@ -163,13 +146,13 @@ export function SearchSourceProvider(Promise, Private, config) {
|
|||
const disabled = _.get(filter, 'meta.disabled');
|
||||
return disabled === undefined || disabled === false;
|
||||
},
|
||||
(filter, state) => {
|
||||
(filter, data) => {
|
||||
if (!config.get('courier:ignoreFilterIfFieldNotInIndex')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ('meta' in filter && 'index' in state) {
|
||||
const field = state.index.fields.byName[filter.meta.key];
|
||||
if ('meta' in filter && 'index' in data) {
|
||||
const field = data.index.fields.byName[filter.meta.key];
|
||||
if (!field) return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -181,42 +164,125 @@ export function SearchSourceProvider(Promise, Private, config) {
|
|||
* PUBLIC API
|
||||
*****/
|
||||
|
||||
|
||||
index(indexPattern) {
|
||||
const state = this._state;
|
||||
|
||||
const hasSource = state.source;
|
||||
const sourceCameFromIp = hasSource && state.source.hasOwnProperty(forIp);
|
||||
const sourceIsForOurIp = sourceCameFromIp && state.source[forIp] === state.index;
|
||||
if (sourceIsForOurIp) {
|
||||
delete state.source;
|
||||
}
|
||||
|
||||
if (indexPattern === undefined) return state.index;
|
||||
if (indexPattern === null) return delete state.index;
|
||||
if (!isIndexPattern(indexPattern)) {
|
||||
throw new TypeError('expected indexPattern to be an IndexPattern duck.');
|
||||
}
|
||||
|
||||
state.index = indexPattern;
|
||||
if (!state.source) {
|
||||
// imply source filtering based on the index pattern, but allow overriding
|
||||
// it by simply setting another value for "source". When index is changed
|
||||
state.source = function () {
|
||||
return indexPattern.getSourceFiltering();
|
||||
};
|
||||
state.source[forIp] = indexPattern;
|
||||
}
|
||||
|
||||
setFields(newFields) {
|
||||
this._fields = newFields;
|
||||
return this;
|
||||
}
|
||||
|
||||
setField = (field, value) => {
|
||||
if (!FIELDS.includes(field)) {
|
||||
throw new Error(`Can't set field '${field}' on SearchSource. Acceptable fields are: ${FIELDS.join(', ')}.`);
|
||||
}
|
||||
|
||||
if (field === 'index') {
|
||||
const fields = this._fields;
|
||||
|
||||
const hasSource = fields.source;
|
||||
const sourceCameFromIp = hasSource && fields.source.hasOwnProperty(forIp);
|
||||
const sourceIsForOurIp = sourceCameFromIp && fields.source[forIp] === fields.index;
|
||||
if (sourceIsForOurIp) {
|
||||
delete fields.source;
|
||||
}
|
||||
|
||||
if (value === null || value === undefined) {
|
||||
delete fields.index;
|
||||
return this;
|
||||
}
|
||||
|
||||
if (!isIndexPattern(value)) {
|
||||
throw new TypeError('expected indexPattern to be an IndexPattern duck.');
|
||||
}
|
||||
|
||||
fields[field] = value;
|
||||
if (!fields.source) {
|
||||
// imply source filtering based on the index pattern, but allow overriding
|
||||
// it by simply setting another field for "source". When index is changed
|
||||
fields.source = function () {
|
||||
return value.getSourceFiltering();
|
||||
};
|
||||
fields.source[forIp] = value;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
if (value == null) {
|
||||
delete this._fields[field];
|
||||
return this;
|
||||
}
|
||||
|
||||
this._fields[field] = value;
|
||||
return this;
|
||||
};
|
||||
|
||||
getId() {
|
||||
return this._id;
|
||||
}
|
||||
|
||||
getFields() {
|
||||
return _.clone(this._fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get fields from the fields
|
||||
*/
|
||||
getField = field => {
|
||||
if (!FIELDS.includes(field)) {
|
||||
throw new Error(`Can't get field '${field}' from SearchSource. Acceptable fields are: ${FIELDS.join(', ')}.`);
|
||||
}
|
||||
|
||||
let searchSource = this;
|
||||
|
||||
while (searchSource) {
|
||||
const value = searchSource._fields[field];
|
||||
if (value !== void 0) {
|
||||
return value;
|
||||
}
|
||||
|
||||
searchSource = searchSource.getParent();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the field from our own fields, don't traverse up the chain
|
||||
*/
|
||||
getOwnField(field) {
|
||||
if (!FIELDS.includes(field)) {
|
||||
throw new Error(`Can't get field '${field}' from SearchSource. Acceptable fields are: ${FIELDS.join(', ')}.`);
|
||||
}
|
||||
|
||||
const value = this._fields[field];
|
||||
if (value !== void 0) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
create() {
|
||||
return new SearchSource();
|
||||
}
|
||||
|
||||
createCopy() {
|
||||
const json = angular.toJson(this._fields);
|
||||
const newSearchSource = new SearchSource(json);
|
||||
// when serializing the internal fields we lose the internal classes used in the index
|
||||
// pattern, so we have to set it again to workaround this behavior
|
||||
newSearchSource.setField('index', this.getField('index'));
|
||||
newSearchSource.setParent(this.getParent());
|
||||
return newSearchSource;
|
||||
}
|
||||
|
||||
createChild(options = {}) {
|
||||
const childSearchSource = new SearchSource();
|
||||
childSearchSource.setParent(this, options);
|
||||
return childSearchSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a searchSource that this source should inherit from
|
||||
* @param {SearchSource} searchSource - the parent searchSource
|
||||
* @return {this} - chainable
|
||||
*/
|
||||
inherits(parent, options = {}) {
|
||||
setParent(parent, options = {}) {
|
||||
this._parent = parent;
|
||||
this._inheritOptions = options;
|
||||
return this;
|
||||
|
@ -230,163 +296,6 @@ export function SearchSourceProvider(Promise, Private, config) {
|
|||
return this._parent || undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporarily prevent this Search from being fetched... not a fan but it's easy
|
||||
*/
|
||||
disable() {
|
||||
this._fetchDisabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse of SearchSource#disable(), only need to call this if source was previously disabled
|
||||
*/
|
||||
enable() {
|
||||
this._fetchDisabled = false;
|
||||
}
|
||||
|
||||
onBeginSegmentedFetch(initFunction) {
|
||||
const self = this;
|
||||
return new Promise((resolve, reject) => {
|
||||
function addRequest() {
|
||||
const defer = Promise.defer();
|
||||
const errorHandler = (request, error) => {
|
||||
reject(error);
|
||||
request.abort();
|
||||
};
|
||||
const req = new SegmentedSearchRequest({ source: self, defer, errorHandler, initFn: initFunction });
|
||||
|
||||
// Return promises created by the completion handler so that
|
||||
// errors will bubble properly
|
||||
return req.getCompletePromise().then(addRequest);
|
||||
}
|
||||
|
||||
addRequest();
|
||||
});
|
||||
}
|
||||
|
||||
addFilterPredicate(predicate) {
|
||||
this._filterPredicates.push(predicate);
|
||||
}
|
||||
|
||||
clone() {
|
||||
const clone = new SearchSource(this.toString());
|
||||
// when serializing the internal state with .toString() we lose the internal classes used in the index
|
||||
// pattern, so we have to set it again to workaround this behavior
|
||||
clone.set('index', this.get('index'));
|
||||
clone.inherits(this.getParent());
|
||||
return clone;
|
||||
}
|
||||
|
||||
makeChild(params) {
|
||||
return new SearchSource().inherits(this, params);
|
||||
}
|
||||
|
||||
new() {
|
||||
return new SearchSource();
|
||||
}
|
||||
|
||||
async getSearchRequestBody() {
|
||||
const searchRequest = await this._flatten();
|
||||
return searchRequest.body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by requests of this search source when they are done
|
||||
* @param {Courier.Request} request
|
||||
* @return {undefined}
|
||||
*/
|
||||
requestIsStopped() {
|
||||
this.activeFetchCount -= 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get values from the state
|
||||
* @param {string} name - The name of the property desired
|
||||
* @return {any} - the value found
|
||||
*/
|
||||
get(name) {
|
||||
let self = this;
|
||||
while (self) {
|
||||
if (self._state[name] !== void 0) return self._state[name];
|
||||
self = self.getParent();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value from our own state, don't traverse up the chain
|
||||
* @param {string} name - The name of the property desired
|
||||
* @return {any} - the value found
|
||||
*/
|
||||
getOwn(name) {
|
||||
if (this._state[name] !== void 0) return this._state[name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the entire state of a SearchSource
|
||||
* @param {object|string} state - The SearchSource's new state, or a
|
||||
* string of the state value to set
|
||||
*/
|
||||
set(state, val) {
|
||||
const self = this;
|
||||
|
||||
if (typeof state === 'string') {
|
||||
// the getter and setter methods check for undefined explicitly
|
||||
// to identify getters and null to identify deletion
|
||||
if (val === undefined) {
|
||||
val = null;
|
||||
}
|
||||
self[state](val);
|
||||
} else {
|
||||
self._state = state;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new dataSource object of the same type
|
||||
* as this, which inherits this dataSource's properties
|
||||
* @return {SearchSource}
|
||||
*/
|
||||
extend() {
|
||||
return new SearchSource().inherits(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* return a simple, encodable object representing the state of the SearchSource
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
toJSON = function () {
|
||||
return _.clone(this._state);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a string representation of the object
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
toString() {
|
||||
return angular.toJson(this.toJSON());
|
||||
}
|
||||
|
||||
/**
|
||||
* Put a request in to the courier that this Source should
|
||||
* be fetched on the next run of the courier
|
||||
* @return {Promise}
|
||||
*/
|
||||
onResults() {
|
||||
const self = this;
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
const defer = Promise.defer();
|
||||
defer.promise.then(resolve, reject);
|
||||
|
||||
const errorHandler = (request, error) => {
|
||||
reject(error);
|
||||
request.abort();
|
||||
};
|
||||
self._createRequest({ defer, errorHandler });
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch this source and reject the returned Promise on error
|
||||
*
|
||||
|
@ -417,7 +326,7 @@ export function SearchSourceProvider(Promise, Private, config) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Cancel all pending requests for this dataSource
|
||||
* Cancel all pending requests for this searchSource
|
||||
* @return {undefined}
|
||||
*/
|
||||
cancelQueued() {
|
||||
|
@ -426,15 +335,6 @@ export function SearchSourceProvider(Promise, Private, config) {
|
|||
.forEach(req => req.abort());
|
||||
}
|
||||
|
||||
/**
|
||||
* Completely destroy the SearchSource.
|
||||
* @return {undefined}
|
||||
*/
|
||||
destroy() {
|
||||
this.cancelQueued();
|
||||
this._requestStartHandlers.length = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a handler that will be notified whenever requests start
|
||||
* @param {Function} handler
|
||||
|
@ -469,6 +369,68 @@ export function SearchSourceProvider(Promise, Private, config) {
|
|||
.then(_.noop);
|
||||
}
|
||||
|
||||
/**
|
||||
* Put a request in to the courier that this Source should
|
||||
* be fetched on the next run of the courier
|
||||
* @return {Promise}
|
||||
*/
|
||||
onResults() {
|
||||
const self = this;
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
const defer = Promise.defer();
|
||||
defer.promise.then(resolve, reject);
|
||||
|
||||
const errorHandler = (request, error) => {
|
||||
reject(error);
|
||||
request.abort();
|
||||
};
|
||||
self._createRequest({ defer, errorHandler });
|
||||
});
|
||||
}
|
||||
|
||||
onBeginSegmentedFetch(initFunction) {
|
||||
const self = this;
|
||||
return new Promise((resolve, reject) => {
|
||||
function addRequest() {
|
||||
const defer = Promise.defer();
|
||||
const errorHandler = (request, error) => {
|
||||
reject(error);
|
||||
request.abort();
|
||||
};
|
||||
const req = new SegmentedSearchRequest({ source: self, defer, errorHandler, initFn: initFunction });
|
||||
|
||||
// Return promises created by the completion handler so that
|
||||
// errors will bubble properly
|
||||
return req.getCompletePromise().then(addRequest);
|
||||
}
|
||||
|
||||
addRequest();
|
||||
});
|
||||
}
|
||||
|
||||
async getSearchRequestBody() {
|
||||
const searchRequest = await this._flatten();
|
||||
return searchRequest.body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by requests of this search source when they are done
|
||||
* @param {Courier.Request} request
|
||||
* @return {undefined}
|
||||
*/
|
||||
requestIsStopped() {
|
||||
this.activeFetchCount -= 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Completely destroy the SearchSource.
|
||||
* @return {undefined}
|
||||
*/
|
||||
destroy() {
|
||||
this.cancelQueued();
|
||||
this._requestStartHandlers.length = 0;
|
||||
}
|
||||
|
||||
/******
|
||||
* PRIVATE APIS
|
||||
|
@ -480,14 +442,6 @@ export function SearchSourceProvider(Promise, Private, config) {
|
|||
.filter(req => req.source === this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type of the DataSource
|
||||
* @return {string}
|
||||
*/
|
||||
_getType() {
|
||||
return 'search';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a common search request object, which should
|
||||
* be put into the pending request queue, for this search
|
||||
|
@ -502,20 +456,20 @@ export function SearchSourceProvider(Promise, Private, config) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Used to merge properties into the state within ._flatten().
|
||||
* The state is passed in and modified by the function
|
||||
* Used to merge properties into the data within ._flatten().
|
||||
* The data is passed in and modified by the function
|
||||
*
|
||||
* @param {object} state - the current merged state
|
||||
* @param {object} data - the current merged data
|
||||
* @param {*} val - the value at `key`
|
||||
* @param {*} key - The key of `val`
|
||||
* @return {undefined}
|
||||
*/
|
||||
_mergeProp(state, val, key) {
|
||||
_mergeProp(data, val, key) {
|
||||
if (typeof val === 'function') {
|
||||
const source = this;
|
||||
return Promise.cast(val(this))
|
||||
.then(function (newVal) {
|
||||
return source._mergeProp(state, newVal, key);
|
||||
return source._mergeProp(data, newVal, key);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -526,17 +480,17 @@ export function SearchSourceProvider(Promise, Private, config) {
|
|||
let filters = Array.isArray(val) ? val : [val];
|
||||
|
||||
filters = filters.filter(filter => {
|
||||
return this._filterPredicates.every(predicate => predicate(filter, state));
|
||||
return this._filterPredicates.every(predicate => predicate(filter, data));
|
||||
});
|
||||
|
||||
state.filters = [...(state.filters || []), ...filters];
|
||||
data.filters = [...(data.filters || []), ...filters];
|
||||
return;
|
||||
case 'index':
|
||||
case 'type':
|
||||
case 'id':
|
||||
case 'highlightAll':
|
||||
if (key && state[key] == null) {
|
||||
state[key] = val;
|
||||
if (key && data[key] == null) {
|
||||
data[key] = val;
|
||||
}
|
||||
return;
|
||||
case 'searchAfter':
|
||||
|
@ -548,14 +502,14 @@ export function SearchSourceProvider(Promise, Private, config) {
|
|||
addToBody();
|
||||
break;
|
||||
case 'sort':
|
||||
val = normalizeSortRequest(val, this.get('index'));
|
||||
val = normalizeSortRequest(val, this.getField('index'));
|
||||
addToBody();
|
||||
break;
|
||||
case 'query':
|
||||
state.query = (state.query || []).concat(val);
|
||||
data.query = (data.query || []).concat(val);
|
||||
break;
|
||||
case 'fields':
|
||||
state[key] = _.uniq([...(state[key] || []), ...val]);
|
||||
data[key] = _.uniq([...(data[key] || []), ...val]);
|
||||
break;
|
||||
default:
|
||||
addToBody();
|
||||
|
@ -565,10 +519,10 @@ export function SearchSourceProvider(Promise, Private, config) {
|
|||
* Add the key and val to the body of the request
|
||||
*/
|
||||
function addToBody() {
|
||||
state.body = state.body || {};
|
||||
data.body = data.body || {};
|
||||
// ignore if we already have a value
|
||||
if (state.body[key] == null) {
|
||||
state.body[key] = val;
|
||||
if (data.body[key] == null) {
|
||||
data.body[key] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -577,15 +531,13 @@ export function SearchSourceProvider(Promise, Private, config) {
|
|||
* Walk the inheritance chain of a source and return it's
|
||||
* flat representation (taking into account merging rules)
|
||||
* @returns {Promise}
|
||||
* @resolved {Object|null} - the flat state of the SearchSource
|
||||
* @resolved {Object|null} - the flat data of the SearchSource
|
||||
*/
|
||||
_flatten() {
|
||||
const type = this._getType();
|
||||
// the merged data of this dataSource and it's ancestors
|
||||
const flatData = {};
|
||||
|
||||
// the merged state of this dataSource and it's ancestors
|
||||
const flatState = {};
|
||||
|
||||
// function used to write each property from each state object in the chain to flat state
|
||||
// function used to write each property from each data object in the chain to flat data
|
||||
const root = this;
|
||||
|
||||
// start the chain at this source
|
||||
|
@ -593,17 +545,17 @@ export function SearchSourceProvider(Promise, Private, config) {
|
|||
|
||||
// call the ittr and return it's promise
|
||||
return (function ittr() {
|
||||
// iterate the _state object (not array) and
|
||||
// iterate the _fields object (not array) and
|
||||
// pass each key:value pair to source._mergeProp. if _mergeProp
|
||||
// returns a promise, then wait for it to complete and call _mergeProp again
|
||||
return Promise.all(_.map(current._state, function ittr(value, key) {
|
||||
return Promise.all(_.map(current._fields, function ittr(value, key) {
|
||||
if (Promise.is(value)) {
|
||||
return value.then(function (value) {
|
||||
return ittr(value, key);
|
||||
});
|
||||
}
|
||||
|
||||
const prom = root._mergeProp(flatState, value, key);
|
||||
const prom = root._mergeProp(flatData, value, key);
|
||||
return Promise.is(prom) ? prom : null;
|
||||
}))
|
||||
.then(function () {
|
||||
|
@ -617,82 +569,80 @@ export function SearchSourceProvider(Promise, Private, config) {
|
|||
});
|
||||
}())
|
||||
.then(function () {
|
||||
if (type === 'search') {
|
||||
// This is down here to prevent the circular dependency
|
||||
flatState.body = flatState.body || {};
|
||||
// This is down here to prevent the circular dependency
|
||||
flatData.body = flatData.body || {};
|
||||
|
||||
const computedFields = flatState.index.getComputedFields();
|
||||
flatState.body.stored_fields = computedFields.storedFields;
|
||||
flatState.body.script_fields = flatState.body.script_fields || {};
|
||||
flatState.body.docvalue_fields = flatState.body.docvalue_fields || [];
|
||||
const computedFields = flatData.index.getComputedFields();
|
||||
flatData.body.stored_fields = computedFields.storedFields;
|
||||
flatData.body.script_fields = flatData.body.script_fields || {};
|
||||
flatData.body.docvalue_fields = flatData.body.docvalue_fields || [];
|
||||
|
||||
_.extend(flatState.body.script_fields, computedFields.scriptFields);
|
||||
flatState.body.docvalue_fields = _.union(flatState.body.docvalue_fields, computedFields.docvalueFields);
|
||||
_.extend(flatData.body.script_fields, computedFields.scriptFields);
|
||||
flatData.body.docvalue_fields = _.union(flatData.body.docvalue_fields, computedFields.docvalueFields);
|
||||
|
||||
if (flatState.body._source) {
|
||||
// exclude source fields for this index pattern specified by the user
|
||||
const filter = fieldWildcardFilter(flatState.body._source.excludes);
|
||||
flatState.body.docvalue_fields = flatState.body.docvalue_fields.filter(filter);
|
||||
}
|
||||
|
||||
// if we only want to search for certain fields
|
||||
const fields = flatState.fields;
|
||||
if (fields) {
|
||||
// filter out the docvalue_fields, and script_fields to only include those that we are concerned with
|
||||
flatState.body.docvalue_fields = _.intersection(flatState.body.docvalue_fields, fields);
|
||||
flatState.body.script_fields = _.pick(flatState.body.script_fields, fields);
|
||||
|
||||
// request the remaining fields from both stored_fields and _source
|
||||
const remainingFields = _.difference(fields, _.keys(flatState.body.script_fields));
|
||||
flatState.body.stored_fields = remainingFields;
|
||||
_.set(flatState.body, '_source.includes', remainingFields);
|
||||
}
|
||||
|
||||
flatState.body.query = buildESQuery(flatState.index, flatState.query, flatState.filters);
|
||||
|
||||
if (flatState.highlightAll != null) {
|
||||
if (flatState.highlightAll && flatState.body.query) {
|
||||
flatState.body.highlight = getHighlightRequest(flatState.body.query, getConfig);
|
||||
}
|
||||
delete flatState.highlightAll;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate a filter into a query to support es 3+
|
||||
* @param {Object} filter - The filter to translate
|
||||
* @return {Object} the query version of that filter
|
||||
*/
|
||||
const translateToQuery = function (filter) {
|
||||
if (!filter) return;
|
||||
|
||||
if (filter.query) {
|
||||
return filter.query;
|
||||
}
|
||||
|
||||
return filter;
|
||||
};
|
||||
|
||||
// re-write filters within filter aggregations
|
||||
(function recurse(aggBranch) {
|
||||
if (!aggBranch) return;
|
||||
Object.keys(aggBranch).forEach(function (id) {
|
||||
const agg = aggBranch[id];
|
||||
|
||||
if (agg.filters) {
|
||||
// translate filters aggregations
|
||||
const filters = agg.filters.filters;
|
||||
|
||||
Object.keys(filters).forEach(function (filterId) {
|
||||
filters[filterId] = translateToQuery(filters[filterId]);
|
||||
});
|
||||
}
|
||||
|
||||
recurse(agg.aggs || agg.aggregations);
|
||||
});
|
||||
}(flatState.body.aggs || flatState.body.aggregations));
|
||||
if (flatData.body._source) {
|
||||
// exclude source fields for this index pattern specified by the user
|
||||
const filter = fieldWildcardFilter(flatData.body._source.excludes);
|
||||
flatData.body.docvalue_fields = flatData.body.docvalue_fields.filter(filter);
|
||||
}
|
||||
|
||||
return flatState;
|
||||
// if we only want to search for certain fields
|
||||
const fields = flatData.fields;
|
||||
if (fields) {
|
||||
// filter out the docvalue_fields, and script_fields to only include those that we are concerned with
|
||||
flatData.body.docvalue_fields = _.intersection(flatData.body.docvalue_fields, fields);
|
||||
flatData.body.script_fields = _.pick(flatData.body.script_fields, fields);
|
||||
|
||||
// request the remaining fields from both stored_fields and _source
|
||||
const remainingFields = _.difference(fields, _.keys(flatData.body.script_fields));
|
||||
flatData.body.stored_fields = remainingFields;
|
||||
_.set(flatData.body, '_source.includes', remainingFields);
|
||||
}
|
||||
|
||||
flatData.body.query = buildESQuery(flatData.index, flatData.query, flatData.filters);
|
||||
|
||||
if (flatData.highlightAll != null) {
|
||||
if (flatData.highlightAll && flatData.body.query) {
|
||||
flatData.body.highlight = getHighlightRequest(flatData.body.query, getConfig);
|
||||
}
|
||||
delete flatData.highlightAll;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate a filter into a query to support es 3+
|
||||
* @param {Object} filter - The filter to translate
|
||||
* @return {Object} the query version of that filter
|
||||
*/
|
||||
const translateToQuery = function (filter) {
|
||||
if (!filter) return;
|
||||
|
||||
if (filter.query) {
|
||||
return filter.query;
|
||||
}
|
||||
|
||||
return filter;
|
||||
};
|
||||
|
||||
// re-write filters within filter aggregations
|
||||
(function recurse(aggBranch) {
|
||||
if (!aggBranch) return;
|
||||
Object.keys(aggBranch).forEach(function (id) {
|
||||
const agg = aggBranch[id];
|
||||
|
||||
if (agg.filters) {
|
||||
// translate filters aggregations
|
||||
const filters = agg.filters.filters;
|
||||
|
||||
Object.keys(filters).forEach(function (filterId) {
|
||||
filters[filterId] = translateToQuery(filters[filterId]);
|
||||
});
|
||||
}
|
||||
|
||||
recurse(agg.aggs || agg.aggregations);
|
||||
});
|
||||
}(flatData.body.aggs || flatData.body.aggregations));
|
||||
|
||||
return flatData;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
*/
|
||||
function getRequestInspectorStats(searchSource) {
|
||||
const stats = {};
|
||||
const index = searchSource.get('index');
|
||||
const index = searchSource.getField('index');
|
||||
|
||||
if (index) {
|
||||
stats['Index pattern'] = {
|
||||
|
|
|
@ -72,7 +72,7 @@ describe('docTable', function () {
|
|||
searchSource = Private(FixturesStubbedSearchSourceProvider);
|
||||
});
|
||||
init($elem, {
|
||||
searchSource: searchSource,
|
||||
searchSource,
|
||||
columns: [],
|
||||
sorting: ['@timestamp', 'desc']
|
||||
});
|
||||
|
@ -89,12 +89,12 @@ describe('docTable', function () {
|
|||
});
|
||||
|
||||
it('should set the indexPattern to that of the searchSource', function () {
|
||||
expect($scope.indexPattern).to.be(searchSource.get('index'));
|
||||
expect($scope.indexPattern).to.be(searchSource.getField('index'));
|
||||
});
|
||||
|
||||
it('should set size and sort on the searchSource', function () {
|
||||
expect($scope.searchSource.sort.called).to.be(true);
|
||||
expect($scope.searchSource.size.called).to.be(true);
|
||||
expect($scope.searchSource.setField.getCall(0).args[0]).to.be('size');
|
||||
expect($scope.searchSource.setField.getCall(1).args[0]).to.be('sort');
|
||||
});
|
||||
|
||||
it('should have an addRows function that increases the row count', function () {
|
||||
|
|
|
@ -94,16 +94,16 @@ uiModules.get('kibana')
|
|||
$scope.$watch('searchSource', function () {
|
||||
if (!$scope.searchSource) return;
|
||||
|
||||
$scope.indexPattern = $scope.searchSource.get('index');
|
||||
$scope.indexPattern = $scope.searchSource.getField('index');
|
||||
|
||||
$scope.searchSource.size(config.get('discover:sampleSize'));
|
||||
$scope.searchSource.sort(getSort($scope.sorting, $scope.indexPattern));
|
||||
$scope.searchSource.setField('size', config.get('discover:sampleSize'));
|
||||
$scope.searchSource.setField('sort', getSort($scope.sorting, $scope.indexPattern));
|
||||
|
||||
// Set the watcher after initialization
|
||||
$scope.$watchCollection('sorting', function (newSort, oldSort) {
|
||||
// Don't react if sort values didn't really change
|
||||
if (newSort === oldSort) return;
|
||||
$scope.searchSource.sort(getSort(newSort, $scope.indexPattern));
|
||||
$scope.searchSource.setField('sort', getSort(newSort, $scope.indexPattern));
|
||||
$scope.searchSource.fetchQueued();
|
||||
});
|
||||
|
||||
|
|
|
@ -82,8 +82,8 @@ const CourierRequestHandlerProvider = function () {
|
|||
// Using callParentStartHandlers: true we make sure, that the parent searchSource
|
||||
// onSearchRequestStart will be called properly even though we use an inherited
|
||||
// search source.
|
||||
const timeFilterSearchSource = searchSource.makeChild({ callParentStartHandlers: true });
|
||||
const requestSearchSource = timeFilterSearchSource.makeChild({ callParentStartHandlers: true });
|
||||
const timeFilterSearchSource = searchSource.createChild({ callParentStartHandlers: true });
|
||||
const requestSearchSource = timeFilterSearchSource.createChild({ callParentStartHandlers: true });
|
||||
|
||||
// For now we need to mirror the history of the passed search source, since
|
||||
// the spy panel wouldn't work otherwise.
|
||||
|
@ -96,7 +96,7 @@ const CourierRequestHandlerProvider = function () {
|
|||
}
|
||||
});
|
||||
|
||||
requestSearchSource.aggs(function () {
|
||||
requestSearchSource.setField('aggs', function () {
|
||||
return aggs.toDsl();
|
||||
});
|
||||
|
||||
|
@ -104,12 +104,12 @@ const CourierRequestHandlerProvider = function () {
|
|||
return aggs.onSearchRequestStart(searchSource, searchRequest);
|
||||
});
|
||||
|
||||
timeFilterSearchSource.set('filter', () => {
|
||||
return getTime(searchSource.get('index'), timeRange);
|
||||
timeFilterSearchSource.setField('filter', () => {
|
||||
return getTime(searchSource.getField('index'), timeRange);
|
||||
});
|
||||
|
||||
requestSearchSource.set('filter', filters);
|
||||
requestSearchSource.set('query', query);
|
||||
requestSearchSource.setField('filter', filters);
|
||||
requestSearchSource.setField('query', query);
|
||||
|
||||
const shouldQuery = (requestBodyHash) => {
|
||||
if (!searchSource.lastQuery || forceFetch) return true;
|
||||
|
|
|
@ -64,8 +64,8 @@ describe('visualize directive', function () {
|
|||
$rootScope.uiState = uiState;
|
||||
$rootScope.searchSource = searchSource;
|
||||
$rootScope.savedObject = {
|
||||
vis: vis,
|
||||
searchSource: searchSource
|
||||
vis,
|
||||
searchSource,
|
||||
};
|
||||
$rootScope.updateState = updateState;
|
||||
|
||||
|
|
|
@ -42,8 +42,8 @@ describe('visualize loader', () => {
|
|||
|
||||
function createSavedObject() {
|
||||
return {
|
||||
vis: vis,
|
||||
searchSource: searchSource
|
||||
vis,
|
||||
searchSource,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -185,9 +185,9 @@ module.directive('mlCustomUrlEditor', function (Private) {
|
|||
|
||||
const searchSourceJSON = response.get('kibanaSavedObjectMeta.searchSourceJSON');
|
||||
if (searchSourceJSON !== undefined) {
|
||||
const searchSource = JSON.parse(searchSourceJSON);
|
||||
filters = _.get(searchSource, 'filter', []);
|
||||
query = searchSource.query;
|
||||
const searchSourceData = JSON.parse(searchSourceJSON);
|
||||
filters = _.get(searchSourceData, 'filter', []);
|
||||
query = searchSourceData.query;
|
||||
}
|
||||
|
||||
// Add time settings to the global state URL parameter with $earliest$ and
|
||||
|
|
|
@ -56,12 +56,12 @@ export function createSearchItems($route) {
|
|||
|
||||
if (indexPattern.id === undefined &&
|
||||
savedSearch.id !== undefined) {
|
||||
indexPattern = searchSource.get('index');
|
||||
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.get('query');
|
||||
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;
|
||||
|
@ -71,7 +71,7 @@ export function createSearchItems($route) {
|
|||
}
|
||||
}
|
||||
|
||||
const fs = searchSource.get('filter');
|
||||
const fs = searchSource.getField('filter');
|
||||
if (fs.length) {
|
||||
filters = fs;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue