= ({ stats, fieldFormat, barColor, compressed,
'xpack.dataVisualizer.dataGrid.field.addFilterAriaLabel',
{
defaultMessage: 'Filter for {fieldName}: "{value}"',
- values: { fieldName, value: fieldValue },
+ values: { fieldName, value: displayValue },
}
)}
- data-test-subj={`dvFieldDataTopValuesAddFilterButton-${fieldName}-${fieldValue}`}
+ data-test-subj={`dvFieldDataTopValuesAddFilterButton-${fieldName}-${displayValue}`}
style={{
minHeight: 'auto',
minWidth: 'auto',
@@ -172,10 +172,10 @@ export const TopValues: FC
= ({ stats, fieldFormat, barColor, compressed,
'xpack.dataVisualizer.dataGrid.field.removeFilterAriaLabel',
{
defaultMessage: 'Filter out {fieldName}: "{value}"',
- values: { fieldName, value: fieldValue },
+ values: { fieldName, value: displayValue },
}
)}
- data-test-subj={`dvFieldDataTopValuesExcludeFilterButton-${fieldName}-${fieldValue}`}
+ data-test-subj={`dvFieldDataTopValuesExcludeFilterButton-${fieldName}-${displayValue}`}
style={{
minHeight: 'auto',
minWidth: 'auto',
diff --git a/x-pack/plugins/data_visualizer/public/application/common/hooks/use_data.ts b/x-pack/plugins/data_visualizer/public/application/common/hooks/use_data.ts
index 65c882ba551d9..9b85720fc1df4 100644
--- a/x-pack/plugins/data_visualizer/public/application/common/hooks/use_data.ts
+++ b/x-pack/plugins/data_visualizer/public/application/common/hooks/use_data.ts
@@ -14,9 +14,9 @@ import { mlTimefilterRefresh$, useTimefilter } from '@kbn/ml-date-picker';
import { merge } from 'rxjs';
import { RandomSampler } from '@kbn/ml-random-sampler-utils';
import { mapAndFlattenFilters } from '@kbn/data-plugin/public';
-import { Query } from '@kbn/es-query';
+import { buildEsQuery, Query } from '@kbn/es-query';
import { SearchQueryLanguage } from '@kbn/ml-query-utils';
-import { createMergedEsQuery } from '../../index_data_visualizer/utils/saved_search_utils';
+import { getEsQueryConfig } from '@kbn/data-plugin/common';
import { useDataDriftStateManagerContext } from '../../data_drift/use_state_manager';
import type { InitialSettings } from '../../data_drift/use_data_drift_result';
import {
@@ -74,7 +74,7 @@ export const useData = (
() => {
const searchQuery =
searchString !== undefined && searchQueryLanguage !== undefined
- ? { query: searchString, language: searchQueryLanguage }
+ ? ({ query: searchString, language: searchQueryLanguage } as Query)
: undefined;
const timefilterActiveBounds = timeRange ?? timefilter.getActiveBounds();
@@ -90,24 +90,24 @@ export const useData = (
runtimeFieldMap: selectedDataView.getRuntimeMappings(),
};
- const refQuery = createMergedEsQuery(
- searchQuery,
+ const refQuery = buildEsQuery(
+ selectedDataView,
+ searchQuery ?? [],
mapAndFlattenFilters([
...queryManager.filterManager.getFilters(),
...(referenceStateManager.filters ?? []),
]),
- selectedDataView,
- uiSettings
+ uiSettings ? getEsQueryConfig(uiSettings) : undefined
);
- const compQuery = createMergedEsQuery(
- searchQuery,
+ const compQuery = buildEsQuery(
+ selectedDataView,
+ searchQuery ?? [],
mapAndFlattenFilters([
...queryManager.filterManager.getFilters(),
...(comparisonStateManager.filters ?? []),
]),
- selectedDataView,
- uiSettings
+ uiSettings ? getEsQueryConfig(uiSettings) : undefined
);
return {
diff --git a/x-pack/plugins/data_visualizer/public/application/data_drift/use_data_drift_result.ts b/x-pack/plugins/data_visualizer/public/application/data_drift/use_data_drift_result.ts
index 07b74677e8ea9..05f24bdcb7b68 100644
--- a/x-pack/plugins/data_visualizer/public/application/data_drift/use_data_drift_result.ts
+++ b/x-pack/plugins/data_visualizer/public/application/data_drift/use_data_drift_result.ts
@@ -8,6 +8,7 @@
import { chunk, cloneDeep, flatten } from 'lodash';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { lastValueFrom } from 'rxjs';
+import { getEsQueryConfig } from '@kbn/data-plugin/common';
import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import type {
@@ -30,7 +31,7 @@ import { computeChi2PValue, type Histogram } from '@kbn/ml-chi2test';
import { mapAndFlattenFilters } from '@kbn/data-plugin/public';
import type { AggregationsMultiTermsBucketKeys } from '@elastic/elasticsearch/lib/api/types';
-import { createMergedEsQuery } from '../index_data_visualizer/utils/saved_search_utils';
+import { buildEsQuery } from '@kbn/es-query';
import { useDataVisualizerKibana } from '../kibana_context';
import { useDataDriftStateManagerContext } from './use_state_manager';
@@ -758,18 +759,18 @@ export const useFetchDataComparisonResult = (
const kqlQuery =
searchString !== undefined && searchQueryLanguage !== undefined
- ? { query: searchString, language: searchQueryLanguage }
+ ? ({ query: searchString, language: searchQueryLanguage } as Query)
: undefined;
const refDataQuery = getDataComparisonQuery({
- searchQuery: createMergedEsQuery(
- kqlQuery,
+ searchQuery: buildEsQuery(
+ currentDataView,
+ kqlQuery ?? [],
mapAndFlattenFilters([
...queryManager.filterManager.getFilters(),
...(referenceStateManager.filters ?? []),
]),
- currentDataView,
- uiSettings
+ uiSettings ? getEsQueryConfig(uiSettings) : undefined
),
datetimeField: currentDataView?.timeFieldName,
runtimeFields,
@@ -827,14 +828,14 @@ export const useFetchDataComparisonResult = (
setLoaded(0.25);
const prodDataQuery = getDataComparisonQuery({
- searchQuery: createMergedEsQuery(
- kqlQuery,
+ searchQuery: buildEsQuery(
+ currentDataView,
+ kqlQuery ?? [],
mapAndFlattenFilters([
...queryManager.filterManager.getFilters(),
...(comparisonStateManager.filters ?? []),
]),
- currentDataView,
- uiSettings
+ uiSettings ? getEsQueryConfig(uiSettings) : undefined
),
datetimeField: currentDataView?.timeFieldName,
runtimeFields,
diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx
index cc17387886071..5d8ebe9e44d57 100644
--- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx
+++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx
@@ -8,6 +8,7 @@
import { css } from '@emotion/react';
import React, { FC, useEffect, useMemo, useState, useCallback, useRef } from 'react';
import type { Required } from 'utility-types';
+import { getEsQueryConfig } from '@kbn/data-plugin/common';
import {
useEuiBreakpoint,
@@ -21,7 +22,7 @@ import {
EuiTitle,
} from '@elastic/eui';
-import { type Filter, FilterStateStore, type Query } from '@kbn/es-query';
+import { type Filter, FilterStateStore, type Query, buildEsQuery } from '@kbn/es-query';
import { generateFilters } from '@kbn/data-plugin/public';
import { DataView, DataViewField } from '@kbn/data-views-plugin/public';
import { usePageUrlState, useUrlState } from '@kbn/ml-url-state';
@@ -62,7 +63,6 @@ import { DocumentCountContent } from '../../../common/components/document_count_
import { OMIT_FIELDS } from '../../../../../common/constants';
import { SearchPanel } from '../search_panel';
import { ActionsPanel } from '../actions_panel';
-import { createMergedEsQuery } from '../../utils/saved_search_utils';
import { DataVisualizerDataViewManagement } from '../data_view_management';
import type { GetAdditionalLinks } from '../../../common/components/results_links';
import { useDataVisualizerGridData } from '../../hooks/use_data_visualizer_grid_data';
@@ -389,14 +389,14 @@ export const IndexDataVisualizerView: FC = (dataVi
language: searchQueryLanguage,
};
- const combinedQuery = createMergedEsQuery(
+ const combinedQuery = buildEsQuery(
+ currentDataView,
{
query: searchString || '',
language: searchQueryLanguage,
},
data.query.filterManager.getFilters() ?? [],
- currentDataView,
- uiSettings
+ uiSettings ? getEsQueryConfig(uiSettings) : undefined
);
setSearchParams({
diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/search_panel/search_bar.tsx b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/search_panel/search_bar.tsx
index 3ad691bbe11ce..d0f6812c4e253 100644
--- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/search_panel/search_bar.tsx
+++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/search_panel/search_bar.tsx
@@ -5,13 +5,13 @@
* 2.0.
*/
-import type { Filter, Query, TimeRange } from '@kbn/es-query';
+import { buildEsQuery, Filter, Query, TimeRange } from '@kbn/es-query';
import { i18n } from '@kbn/i18n';
import React, { useEffect, useState } from 'react';
import { isDefined } from '@kbn/ml-is-defined';
import { DataView } from '@kbn/data-views-plugin/common';
import type { SearchQueryLanguage } from '@kbn/ml-query-utils';
-import { createMergedEsQuery } from '../../utils/saved_search_utils';
+import { getEsQueryConfig } from '@kbn/data-plugin/common';
import { useDataVisualizerKibana } from '../../../kibana_context';
export const SearchPanelContent = ({
@@ -63,16 +63,17 @@ export const SearchPanelContent = ({
const searchHandler = ({ query, filters }: { query?: Query; filters?: Filter[] }) => {
const mergedQuery = isDefined(query) ? query : searchInput;
const mergedFilters = isDefined(filters) ? filters : queryManager.filterManager.getFilters();
+
try {
if (mergedFilters) {
queryManager.filterManager.setFilters(mergedFilters);
}
- const combinedQuery = createMergedEsQuery(
- mergedQuery,
- queryManager.filterManager.getFilters() ?? [],
+ const combinedQuery = buildEsQuery(
dataView,
- uiSettings
+ mergedQuery ? [mergedQuery] : [],
+ queryManager.filterManager.getFilters() ?? [],
+ uiSettings ? getEsQueryConfig(uiSettings) : undefined
);
setSearchParams({
diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/hooks/use_data_visualizer_grid_data.ts b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/hooks/use_data_visualizer_grid_data.ts
index b012d049ae04f..4570a2019af26 100644
--- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/hooks/use_data_visualizer_grid_data.ts
+++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/hooks/use_data_visualizer_grid_data.ts
@@ -137,10 +137,11 @@ export const useDataVisualizerGridData = (
});
if (searchData === undefined || dataVisualizerListState.searchString !== '') {
- if (dataVisualizerListState.filters) {
+ if (filterManager) {
const globalFilters = filterManager?.getGlobalFilters();
- if (filterManager) filterManager.setFilters(dataVisualizerListState.filters);
+ if (dataVisualizerListState.filters)
+ filterManager.setFilters(dataVisualizerListState.filters);
if (globalFilters) filterManager?.addFilters(globalFilters);
}
return {
@@ -169,6 +170,7 @@ export const useDataVisualizerGridData = (
currentFilters,
}),
lastRefresh,
+ data.query.filterManager,
]);
const _timeBuckets = useTimeBuckets();
diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/utils/saved_search_utils.test.ts b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/utils/saved_search_utils.test.ts
index c43483a34e34c..2b25a5e8d2b8c 100644
--- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/utils/saved_search_utils.test.ts
+++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/utils/saved_search_utils.test.ts
@@ -5,14 +5,10 @@
* 2.0.
*/
-import {
- getQueryFromSavedSearchObject,
- createMergedEsQuery,
- getEsQueryFromSavedSearch,
-} from './saved_search_utils';
+import { getQueryFromSavedSearchObject, getEsQueryFromSavedSearch } from './saved_search_utils';
import type { SavedSearchSavedObject } from '../../../../common/types';
import type { SavedSearch } from '@kbn/saved-search-plugin/public';
-import { type Filter, FilterStateStore } from '@kbn/es-query';
+import { FilterStateStore } from '@kbn/es-query';
import { stubbedSavedObjectIndexPattern } from '@kbn/data-views-plugin/common/data_view.stub';
import { DataView } from '@kbn/data-views-plugin/public';
import { fieldFormatsMock } from '@kbn/field-formats-plugin/common/mocks';
@@ -217,80 +213,6 @@ describe('getQueryFromSavedSearchObject()', () => {
});
});
-describe('createMergedEsQuery()', () => {
- const luceneQuery = {
- query: 'responsetime:>50',
- language: 'lucene',
- };
- const kqlQuery = {
- query: 'responsetime > 49',
- language: 'kuery',
- };
- const mockFilters: Filter[] = [
- {
- meta: {
- index: '90a978e0-1c80-11ec-b1d7-f7e5cf21b9e0',
- negate: false,
- disabled: false,
- alias: null,
- type: 'phrase',
- key: 'airline',
- params: {
- query: 'ASA',
- },
- },
- query: {
- match: {
- airline: {
- query: 'ASA',
- type: 'phrase',
- },
- },
- },
- $state: {
- store: 'appState' as FilterStateStore,
- },
- },
- ];
-
- it('return formatted ES bool query with both the original query and filters combined', () => {
- expect(createMergedEsQuery(luceneQuery, mockFilters)).toEqual({
- bool: {
- filter: [{ match_phrase: { airline: { query: 'ASA' } } }],
- must: [{ query_string: { query: 'responsetime:>50' } }],
- must_not: [],
- should: [],
- },
- });
- expect(createMergedEsQuery(kqlQuery, mockFilters)).toEqual({
- bool: {
- filter: [{ match_phrase: { airline: { query: 'ASA' } } }],
- minimum_should_match: 1,
- must_not: [],
- should: [{ range: { responsetime: { gt: '49' } } }],
- },
- });
- });
- it('return formatted ES bool query without filters ', () => {
- expect(createMergedEsQuery(luceneQuery)).toEqual({
- bool: {
- filter: [],
- must: [{ query_string: { query: 'responsetime:>50' } }],
- must_not: [],
- should: [],
- },
- });
- expect(createMergedEsQuery(kqlQuery)).toEqual({
- bool: {
- filter: [],
- minimum_should_match: 1,
- must_not: [],
- should: [{ range: { responsetime: { gt: '49' } } }],
- },
- });
- });
-});
-
describe('getEsQueryFromSavedSearch()', () => {
it('return undefined if saved search is not provided', () => {
expect(
diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/utils/saved_search_utils.ts b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/utils/saved_search_utils.ts
index 04bc52bf08057..3ecc8a3a7a3d8 100644
--- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/utils/saved_search_utils.ts
+++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/utils/saved_search_utils.ts
@@ -9,22 +9,15 @@
// `x-pack/plugins/apm/public/components/app/correlations/progress_controls.tsx`
import { cloneDeep } from 'lodash';
import { IUiSettingsClient } from '@kbn/core/public';
-import {
- fromKueryExpression,
- toElasticsearchQuery,
- buildQueryFromFilters,
- buildEsQuery,
- Query,
- Filter,
- AggregateQuery,
-} from '@kbn/es-query';
+import { buildEsQuery, Query, Filter } from '@kbn/es-query';
import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import { DataView } from '@kbn/data-views-plugin/public';
import type { SavedSearch } from '@kbn/saved-search-plugin/public';
-import { getEsQueryConfig, isQuery, SearchSource } from '@kbn/data-plugin/common';
+import { getEsQueryConfig, SearchSource } from '@kbn/data-plugin/common';
import { FilterManager, mapAndFlattenFilters } from '@kbn/data-plugin/public';
import { getDefaultDSLQuery } from '@kbn/ml-query-utils';
-import { SEARCH_QUERY_LANGUAGE, SearchQueryLanguage } from '@kbn/ml-query-utils';
+import { SearchQueryLanguage } from '@kbn/ml-query-utils';
+import { isDefined } from '@kbn/ml-is-defined';
import { isSavedSearchSavedObject, SavedSearchSavedObject } from '../../../../common/types';
/**
@@ -59,53 +52,8 @@ export function getQueryFromSavedSearchObject(savedSearch: SavedSearchSavedObjec
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
- */
-export function createMergedEsQuery(
- query?: Query | AggregateQuery | undefined,
- filters?: Filter[],
- dataView?: DataView,
- uiSettings?: IUiSettingsClient
-) {
- let combinedQuery = getDefaultDSLQuery() as QueryDslQueryContainer;
-
- if (isQuery(query) && query.language === SEARCH_QUERY_LANGUAGE.KUERY) {
- const ast = fromKueryExpression(query.query);
- if (query.query !== '') {
- combinedQuery = toElasticsearchQuery(ast, dataView);
- }
- if (combinedQuery.bool !== undefined) {
- const filterQuery = 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 = buildEsQuery(
- dataView,
- query ? [query] : [],
- filters ? filters : [],
- uiSettings ? getEsQueryConfig(uiSettings) : undefined
- );
- }
-
- return combinedQuery;
-}
-
-function getSavedSearchSource(savedSearch: SavedSearch) {
- return savedSearch &&
+function getSavedSearchSource(savedSearch?: SavedSearch | null) {
+ return isDefined(savedSearch) &&
'searchSource' in savedSearch &&
savedSearch?.searchSource instanceof SearchSource
? savedSearch.searchSource
@@ -131,11 +79,15 @@ export function getEsQueryFromSavedSearch({
filters?: Filter[];
filterManager?: FilterManager;
}) {
- if (!dataView || !savedSearch) return;
+ if (!dataView && !savedSearch) return;
const userQuery = query;
const userFilters = filters;
+ if (filterManager && userFilters) {
+ filterManager.addFilters(userFilters);
+ }
+
const savedSearchSource = getSavedSearchSource(savedSearch);
// If saved search has a search source with nested parent
@@ -146,8 +98,8 @@ export function getEsQueryFromSavedSearch({
// 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(savedSearch.searchSource.getSearchRequestBody()?.query) ?? getDefaultDSLQuery();
- const timeField = savedSearch.searchSource.getField('index')?.timeFieldName;
+ cloneDeep(savedSearchSource.getSearchRequestBody()?.query) ?? getDefaultDSLQuery();
+ const timeField = savedSearchSource.getField('index')?.timeFieldName;
if (Array.isArray(savedQuery.bool.filter) && timeField !== undefined) {
savedQuery.bool.filter = savedQuery.bool.filter.filter(
@@ -155,6 +107,7 @@ export function getEsQueryFromSavedSearch({
!(c.hasOwnProperty('range') && c.range?.hasOwnProperty(timeField))
);
}
+
return {
searchQuery: savedQuery,
searchString: userQuery.query,
@@ -163,39 +116,38 @@ export function getEsQueryFromSavedSearch({
}
// 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 : [],
+ if (
+ !savedSearch &&
+ (userQuery || userFilters || (filterManager && filterManager.getGlobalFilters()?.length > 0))
+ ) {
+ const combinedQuery = buildEsQuery(
dataView,
- uiSettings
+ userQuery ?? [],
+ filterManager?.getFilters() ?? [],
+ uiSettings ? getEsQueryConfig(uiSettings) : undefined
);
return {
searchQuery: combinedQuery,
- searchString: userQuery.query,
- queryLanguage: userQuery.language as SearchQueryLanguage,
+ searchString: userQuery?.query ?? '',
+ queryLanguage: (userQuery?.language ?? 'kuery') as SearchQueryLanguage,
};
}
// 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?.getGlobalFilters();
// FIXME: Add support for AggregateQuery type #150091
const currentQuery = userQuery ?? (savedSearchSource.getField('query') as Query);
const currentFilters =
userFilters ?? mapAndFlattenFilters(savedSearchSource.getField('filter') as Filter[]);
- if (filterManager) filterManager.setFilters(currentFilters);
- if (globalFilters) filterManager?.addFilters(globalFilters);
+ if (filterManager) filterManager.addFilters(currentFilters);
- const combinedQuery = createMergedEsQuery(
+ const combinedQuery = buildEsQuery(
+ dataView,
currentQuery,
filterManager ? filterManager?.getFilters() : currentFilters,
- dataView,
- uiSettings
+ uiSettings ? getEsQueryConfig(uiSettings) : undefined
);
return {