"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createMergedEsQuery = createMergedEsQuery; exports.getEsQueryFromSavedSearch = getEsQueryFromSavedSearch; exports.getQueryFromSavedSearchObject = getQueryFromSavedSearchObject; exports.isSavedSearchSavedObject = isSavedSearchSavedObject; var _lodash = require("lodash"); var _common = require("@kbn/data-plugin/common"); var _public = require("@kbn/data-plugin/public"); var _esQuery = require("@kbn/es-query"); var _mlIsPopulatedObject = require("@kbn/ml-is-populated-object"); var _mlQueryUtils = require("@kbn/ml-query-utils"); /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ // TODO Consolidate with duplicate saved search utils file in // `x-pack/plugins/data_visualizer/public/application/index_data_visualizer/utils/saved_search_utils.ts` function isSavedSearchSavedObject(arg) { return (0, _mlIsPopulatedObject.isPopulatedObject)(arg, ['id', 'type', 'attributes']); } /** * Parse the stringified searchSourceJSON * from a saved search or saved search object */ function getQueryFromSavedSearchObject(savedSearch) { var _savedSearch$attribut; const search = isSavedSearchSavedObject(savedSearch) ? savedSearch === null || savedSearch === void 0 ? void 0 : (_savedSearch$attribut = savedSearch.attributes) === null || _savedSearch$attribut === void 0 ? void 0 : _savedSearch$attribut.kibanaSavedObjectMeta : // @ts-ignore savedSearch === null || savedSearch === void 0 ? void 0 : savedSearch.kibanaSavedObjectMeta; const parsed = typeof (search === null || search === void 0 ? void 0 : search.searchSourceJSON) === 'string' ? JSON.parse(search.searchSourceJSON) : undefined; // Remove indexRefName because saved search might no longer be relevant // if user modifies the query or filter // after opening a saved search if (parsed && Array.isArray(parsed.filter)) { parsed.filter.forEach(f => { // @ts-expect-error indexRefName does appear in meta for newly created saved search f.meta.indexRefName = undefined; }); } return parsed; } /** * Create an Elasticsearch query that combines both lucene/kql query string and filters * Should also form a valid query if only the query or filters is provided */ function createMergedEsQuery(query, filters, dataView, uiSettings) { let combinedQuery = (0, _mlQueryUtils.getDefaultDSLQuery)(); // FIXME: Add support for AggregateQuery type #150091 if ((0, _public.isQuery)(query) && query.language === _mlQueryUtils.SEARCH_QUERY_LANGUAGE.KUERY) { const ast = (0, _esQuery.fromKueryExpression)(query.query); if (query.query !== '') { combinedQuery = (0, _esQuery.toElasticsearchQuery)(ast, dataView); } if (combinedQuery.bool !== undefined) { const filterQuery = (0, _esQuery.buildQueryFromFilters)(filters, dataView); if (!Array.isArray(combinedQuery.bool.filter)) { combinedQuery.bool.filter = combinedQuery.bool.filter === undefined ? [] : [combinedQuery.bool.filter]; } if (!Array.isArray(combinedQuery.bool.must_not)) { combinedQuery.bool.must_not = combinedQuery.bool.must_not === undefined ? [] : [combinedQuery.bool.must_not]; } combinedQuery.bool.filter = [...combinedQuery.bool.filter, ...filterQuery.filter]; combinedQuery.bool.must_not = [...combinedQuery.bool.must_not, ...filterQuery.must_not]; } } else { combinedQuery = (0, _esQuery.buildEsQuery)(dataView, query ? [query] : [], filters ? filters : [], uiSettings ? (0, _common.getEsQueryConfig)(uiSettings) : undefined); } return combinedQuery; } function getSavedSearchSource(savedSearch) { return savedSearch && 'searchSource' in savedSearch && (savedSearch === null || savedSearch === void 0 ? void 0 : savedSearch.searchSource) instanceof _common.SearchSource ? savedSearch.searchSource : undefined; } /** * Extract query data from the saved search object * with overrides from the provided query data and/or filters */ function getEsQueryFromSavedSearch({ dataView, uiSettings, savedSearch, query, filters, filterManager }) { if (!dataView || !savedSearch) return; const userQuery = query; const userFilters = filters; const savedSearchSource = getSavedSearchSource(savedSearch); // If saved search has a search source with nested parent // e.g. a search coming from Dashboard saved search embeddable // which already combines both the saved search's original query/filters and the Dashboard's // then no need to process any further if (savedSearchSource && savedSearchSource.getParent() !== undefined && userQuery) { var _cloneDeep, _savedSearch$searchSo, _savedSearch$searchSo2; // Flattened query from search source may contain a clause that narrows the time range // which might interfere with global time pickers so we need to remove const savedQuery = (_cloneDeep = (0, _lodash.cloneDeep)((_savedSearch$searchSo = savedSearch.searchSource.getSearchRequestBody()) === null || _savedSearch$searchSo === void 0 ? void 0 : _savedSearch$searchSo.query)) !== null && _cloneDeep !== void 0 ? _cloneDeep : (0, _mlQueryUtils.getDefaultDSLQuery)(); const timeField = (_savedSearch$searchSo2 = savedSearch.searchSource.getField('index')) === null || _savedSearch$searchSo2 === void 0 ? void 0 : _savedSearch$searchSo2.timeFieldName; if (Array.isArray(savedQuery.bool.filter) && timeField !== undefined) { savedQuery.bool.filter = savedQuery.bool.filter.filter(c => { var _c$range; return !(c.hasOwnProperty('range') && (_c$range = c.range) !== null && _c$range !== void 0 && _c$range.hasOwnProperty(timeField)); }); } return { searchQuery: savedQuery, searchString: userQuery.query, queryLanguage: userQuery.language }; } // If no saved search available, use user's query and filters if (!savedSearch && userQuery) { if (filterManager && userFilters) filterManager.addFilters(userFilters); const combinedQuery = createMergedEsQuery(userQuery, Array.isArray(userFilters) ? userFilters : [], dataView, uiSettings); return { searchQuery: combinedQuery, searchString: userQuery.query, queryLanguage: userQuery.language }; } // If saved search available, merge saved search with the latest user query or filters // which might differ from extracted saved search data if (savedSearchSource) { const globalFilters = filterManager === null || filterManager === void 0 ? void 0 : filterManager.getGlobalFilters(); // FIXME: Add support for AggregateQuery type #150091 const currentQuery = userQuery !== null && userQuery !== void 0 ? userQuery : savedSearchSource.getField('query'); const currentFilters = userFilters !== null && userFilters !== void 0 ? userFilters : (0, _public.mapAndFlattenFilters)(savedSearchSource.getField('filter')); if (filterManager) filterManager.setFilters(currentFilters); if (globalFilters) filterManager === null || filterManager === void 0 ? void 0 : filterManager.addFilters(globalFilters); const combinedQuery = createMergedEsQuery(currentQuery, filterManager ? filterManager === null || filterManager === void 0 ? void 0 : filterManager.getFilters() : currentFilters, dataView, uiSettings); return { searchQuery: combinedQuery, searchString: currentQuery.query, queryLanguage: currentQuery.language }; } }