diff --git a/packages/kbn-es-query/src/es_query/__tests__/_migrate_filter.js b/packages/kbn-es-query/src/es_query/__tests__/_migrate_filter.js deleted file mode 100644 index d9f559987f58b21..000000000000000 --- a/packages/kbn-es-query/src/es_query/__tests__/_migrate_filter.js +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import expect from '@kbn/expect'; -import _ from 'lodash'; -import { migrateFilter } from '../migrate_filter'; - -describe('migrateFilter', function () { - - const oldMatchPhraseFilter = { - match: { - fieldFoo: { - query: 'foobar', - type: 'phrase' - } - } - }; - - const newMatchPhraseFilter = { - match_phrase: { - fieldFoo: { - query: 'foobar' - } - } - }; - - // https://github.com/elastic/elasticsearch/pull/17508 - it('should migrate match filters of type phrase', function () { - const migratedFilter = migrateFilter(oldMatchPhraseFilter); - expect(_.isEqual(migratedFilter, newMatchPhraseFilter)).to.be(true); - }); - - it('should not modify the original filter', function () { - const oldMatchPhraseFilterCopy = _.clone(oldMatchPhraseFilter, true); - migrateFilter(oldMatchPhraseFilter); - expect(_.isEqual(oldMatchPhraseFilter, oldMatchPhraseFilterCopy)).to.be(true); - }); - - it('should return the original filter if no migration is necessary', function () { - const originalFilter = { - match_all: {} - }; - const migratedFilter = migrateFilter(originalFilter); - expect(migratedFilter).to.be(originalFilter); - expect(_.isEqual(migratedFilter, originalFilter)).to.be(true); - }); - -}); diff --git a/packages/kbn-es-query/src/es_query/__tests__/from_filters.js b/packages/kbn-es-query/src/es_query/__tests__/from_filters.js deleted file mode 100644 index 676992e4dddc865..000000000000000 --- a/packages/kbn-es-query/src/es_query/__tests__/from_filters.js +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import expect from '@kbn/expect'; -import { buildQueryFromFilters } from '../from_filters'; - -describe('build query', function () { - describe('buildQueryFromFilters', function () { - it('should return the parameters of an Elasticsearch bool query', function () { - const result = buildQueryFromFilters([]); - const expected = { - must: [], - filter: [], - should: [], - must_not: [], - }; - expect(result).to.eql(expected); - }); - - it('should transform an array of kibana filters into ES queries combined in the bool clauses', function () { - const filters = [ - { - match_all: {}, - meta: { type: 'match_all' }, - }, - { - exists: { field: 'foo' }, - meta: { type: 'exists' }, - }, - ]; - - const expectedESQueries = [ - { match_all: {} }, - { exists: { field: 'foo' } }, - ]; - - const result = buildQueryFromFilters(filters); - - expect(result.filter).to.eql(expectedESQueries); - }); - - it('should remove disabled filters', function () { - const filters = [ - { - match_all: {}, - meta: { type: 'match_all', negate: true, disabled: true }, - }, - ]; - - const expectedESQueries = []; - - const result = buildQueryFromFilters(filters); - - expect(result.must_not).to.eql(expectedESQueries); - }); - - it('should remove falsy filters', function () { - const filters = [null, undefined]; - - const expectedESQueries = []; - - const result = buildQueryFromFilters(filters); - - expect(result.must_not).to.eql(expectedESQueries); - expect(result.must).to.eql(expectedESQueries); - }); - - it('should place negated filters in the must_not clause', function () { - const filters = [ - { - match_all: {}, - meta: { type: 'match_all', negate: true }, - }, - ]; - - const expectedESQueries = [{ match_all: {} }]; - - const result = buildQueryFromFilters(filters); - - expect(result.must_not).to.eql(expectedESQueries); - }); - - it('should translate old ES filter syntax into ES 5+ query objects', function () { - const filters = [ - { - query: { exists: { field: 'foo' } }, - meta: { type: 'exists' }, - }, - ]; - - const expectedESQueries = [ - { - exists: { field: 'foo' }, - }, - ]; - - const result = buildQueryFromFilters(filters); - - expect(result.filter).to.eql(expectedESQueries); - }); - - it('should migrate deprecated match syntax', function () { - const filters = [ - { - query: { match: { extension: { query: 'foo', type: 'phrase' } } }, - meta: { type: 'phrase' }, - }, - ]; - - const expectedESQueries = [ - { - match_phrase: { extension: { query: 'foo' } }, - }, - ]; - - const result = buildQueryFromFilters(filters); - - expect(result.filter).to.eql(expectedESQueries); - }); - - it('should not add query:queryString:options to query_string filters', function () { - const filters = [ - { - query: { query_string: { query: 'foo' } }, - meta: { type: 'query_string' }, - }, - ]; - const expectedESQueries = [{ query_string: { query: 'foo' } }]; - - const result = buildQueryFromFilters(filters); - - expect(result.filter).to.eql(expectedESQueries); - }); - }); -}); diff --git a/packages/kbn-es-query/src/es_query/__tests__/from_lucene.js b/packages/kbn-es-query/src/es_query/__tests__/from_lucene.js deleted file mode 100644 index 4361659021bd5ad..000000000000000 --- a/packages/kbn-es-query/src/es_query/__tests__/from_lucene.js +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import expect from '@kbn/expect'; -import { buildQueryFromLucene } from '../from_lucene'; -import { decorateQuery } from '../decorate_query'; -import { luceneStringToDsl } from '../lucene_string_to_dsl'; - -describe('build query', function () { - - describe('buildQueryFromLucene', function () { - - it('should return the parameters of an Elasticsearch bool query', function () { - const result = buildQueryFromLucene(); - const expected = { - must: [], - filter: [], - should: [], - must_not: [], - }; - expect(result).to.eql(expected); - }); - - it('should transform an array of lucene queries into ES queries combined in the bool\'s must clause', function () { - const queries = [ - { query: 'foo:bar', language: 'lucene' }, - { query: 'bar:baz', language: 'lucene' }, - ]; - - const expectedESQueries = queries.map( - (query) => { - return decorateQuery(luceneStringToDsl(query.query), {}); - } - ); - - const result = buildQueryFromLucene(queries, {}); - - expect(result.must).to.eql(expectedESQueries); - }); - - it('should also accept queries in ES query DSL format, simply passing them through', function () { - const queries = [ - { query: { match_all: {} }, language: 'lucene' }, - ]; - - const result = buildQueryFromLucene(queries, {}); - - expect(result.must).to.eql([queries[0].query]); - }); - - }); - - it('should accept a date format in the decorated queries and combine that into the bool\'s must clause', function () { - const queries = [ - { query: 'foo:bar', language: 'lucene' }, - { query: 'bar:baz', language: 'lucene' }, - ]; - const dateFormatTZ = 'America/Phoenix'; - - const expectedESQueries = queries.map( - (query) => { - return decorateQuery(luceneStringToDsl(query.query), {}, dateFormatTZ); - } - ); - - const result = buildQueryFromLucene(queries, {}, dateFormatTZ); - - expect(result.must).to.eql(expectedESQueries); - }); - -}); diff --git a/packages/kbn-es-query/src/es_query/migrate_filter.js b/packages/kbn-es-query/src/es_query/migrate_filter.js deleted file mode 100644 index b74fc485a6184f5..000000000000000 --- a/packages/kbn-es-query/src/es_query/migrate_filter.js +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import _ from 'lodash'; -import { getConvertedValueForField } from '../utils/filters'; - -export function migrateFilter(filter, indexPattern) { - if (filter.match) { - const fieldName = Object.keys(filter.match)[0]; - - - if (isMatchPhraseFilter(filter, fieldName)) { - const params = _.get(filter, ['match', fieldName]); - if (indexPattern) { - const field = indexPattern.fields.find(f => f.name === fieldName); - if (field) { - params.query = getConvertedValueForField(field, params.query); - } - } - return { - match_phrase: { - [fieldName]: _.omit(params, 'type'), - }, - }; - } - } - - return filter; -} - -function isMatchPhraseFilter(filter, fieldName) { - return _.get(filter, ['match', fieldName, 'type']) === 'phrase'; -} diff --git a/packages/kbn-es-query/src/index.d.ts b/packages/kbn-es-query/src/index.d.ts index c06cef6367fe78c..79e6903b1864488 100644 --- a/packages/kbn-es-query/src/index.d.ts +++ b/packages/kbn-es-query/src/index.d.ts @@ -17,5 +17,4 @@ * under the License. */ -export * from './es_query'; export * from './kuery'; diff --git a/packages/kbn-es-query/src/index.js b/packages/kbn-es-query/src/index.js index 963999bd0999b2d..79e6903b1864488 100644 --- a/packages/kbn-es-query/src/index.js +++ b/packages/kbn-es-query/src/index.js @@ -18,4 +18,3 @@ */ export * from './kuery'; -export * from './es_query'; diff --git a/packages/kbn-es-query/src/kuery/ast/ast.d.ts b/packages/kbn-es-query/src/kuery/ast/ast.d.ts index 06f4940e8ed3b5a..ef3d0ee82887460 100644 --- a/packages/kbn-es-query/src/kuery/ast/ast.d.ts +++ b/packages/kbn-es-query/src/kuery/ast/ast.d.ts @@ -25,18 +25,26 @@ import { JsonObject } from '..'; export type KueryNode = any; +export type DslQuery = any; + export interface KueryParseOptions { helpers: { [key: string]: any; }; startRule: string; + allowLeadingWildcards: boolean; } export function fromKueryExpression( - expression: string, - parseOptions?: KueryParseOptions + expression: string | DslQuery, + parseOptions?: Partial ): KueryNode; -export function toElasticsearchQuery(node: KueryNode, indexPattern?: any): JsonObject; +export function toElasticsearchQuery( + node: KueryNode, + indexPattern?: any, + config?: Record, + context?: Record +): JsonObject; export function doesKueryExpressionHaveLuceneSyntaxError(expression: string): boolean; diff --git a/src/es_archiver/lib/indices/create_index_stream.js b/src/es_archiver/lib/indices/create_index_stream.js index 746f0d689ce56cd..0daccbee91bd0c6 100644 --- a/src/es_archiver/lib/indices/create_index_stream.js +++ b/src/es_archiver/lib/indices/create_index_stream.js @@ -41,9 +41,6 @@ export function createCreateIndexStream({ client, stats, skipExisting, log }) { async function handleIndex(record) { const { index, settings, mappings, aliases } = record.value; - - // Determine if the mapping belongs to a pre-7.0 instance, for BWC tests, mainly - const isPre7Mapping = !!mappings && Object.keys(mappings).length > 0 && !mappings.properties; const isKibana = index.startsWith('.kibana'); async function attemptToCreate(attemptNumber = 1) { @@ -55,7 +52,6 @@ export function createCreateIndexStream({ client, stats, skipExisting, log }) { await client.indices.create({ method: 'PUT', index, - include_type_name: isPre7Mapping, body: { settings, mappings, diff --git a/src/legacy/core_plugins/data/public/index_patterns/fields/field.ts b/src/legacy/core_plugins/data/public/index_patterns/fields/field.ts index dc5023795bf19bd..bb0274aa071c9c9 100644 --- a/src/legacy/core_plugins/data/public/index_patterns/fields/field.ts +++ b/src/legacy/core_plugins/data/public/index_patterns/fields/field.ts @@ -28,34 +28,14 @@ import { shortenDottedString } from '../../../../../core_plugins/kibana/common/u import { IndexPattern } from '../index_patterns'; import { getNotifications } from '../services'; -import { getKbnFieldType } from '../../../../../../plugins/data/public'; - -interface FieldSubType { - multi?: { parent: string }; - nested?: { path: string }; -} +import { getKbnFieldType, IFieldType, IFieldSubType } from '../../../../../../plugins/data/public'; export type FieldSpec = Record; -export interface FieldType { - name: string; - type: string; - script?: string; - lang?: string; - count?: number; - // esTypes might be undefined on old index patterns that have not been refreshed since we added - // this prop. It is also undefined on scripted fields. - esTypes?: string[]; - aggregatable?: boolean; - filterable?: boolean; - searchable?: boolean; - sortable?: boolean; - visualizable?: boolean; - readFromDocValues?: boolean; - scripted?: boolean; - subType?: FieldSubType; - displayName?: string; - format?: any; -} + +/** @deprecated + * Please use IFieldType instead + * */ +export type FieldType = IFieldType; export class Field implements FieldType { name: string; @@ -72,7 +52,7 @@ export class Field implements FieldType { sortable?: boolean; visualizable?: boolean; scripted?: boolean; - subType?: FieldSubType; + subType?: IFieldSubType; displayName?: string; format: any; routes: Record = { diff --git a/src/legacy/core_plugins/data/public/index_patterns/index_patterns/index_pattern.ts b/src/legacy/core_plugins/data/public/index_patterns/index_patterns/index_pattern.ts index bf0d79e960d9b8f..ac1a43fd56c8ff8 100644 --- a/src/legacy/core_plugins/data/public/index_patterns/index_patterns/index_pattern.ts +++ b/src/legacy/core_plugins/data/public/index_patterns/index_patterns/index_pattern.ts @@ -37,19 +37,16 @@ import { createFieldsFetcher } from './_fields_fetcher'; import { formatHitProvider } from './format_hit'; import { flattenHitWrapper } from './flatten_hit'; import { IIndexPatternsApiClient } from './index_patterns_api_client'; -import { ES_FIELD_TYPES } from '../../../../../../plugins/data/common'; +import { ES_FIELD_TYPES, IIndexPattern } from '../../../../../../plugins/data/public'; import { getNotifications } from '../services'; const MAX_ATTEMPTS_TO_RESOLVE_CONFLICTS = 3; const type = 'index-pattern'; -export interface StaticIndexPattern { - fields: FieldType[]; - title: string; - id?: string; - type?: string; - timeFieldName?: string; -} +/** @deprecated + * Please use IIndexPattern instead + * */ +export type StaticIndexPattern = IIndexPattern; export class IndexPattern implements StaticIndexPattern { [key: string]: any; diff --git a/src/legacy/core_plugins/timelion/public/vis/timelion_request_handler.ts b/src/legacy/core_plugins/timelion/public/vis/timelion_request_handler.ts index 6239e4027c392a1..649b1a41e0ece4a 100644 --- a/src/legacy/core_plugins/timelion/public/vis/timelion_request_handler.ts +++ b/src/legacy/core_plugins/timelion/public/vis/timelion_request_handler.ts @@ -17,16 +17,14 @@ * under the License. */ -// @ts-ignore -import { buildEsQuery, getEsQueryConfig } from '@kbn/es-query'; // @ts-ignore import { timezoneProvider } from 'ui/vis/lib/timezone'; import { KIBANA_CONTEXT_NAME } from 'src/plugins/expressions/public'; import { Query } from 'src/legacy/core_plugins/data/public'; -import { TimeRange, esFilters } from 'src/plugins/data/public'; import { VisParams } from 'ui/vis'; import { i18n } from '@kbn/i18n'; import { TimelionVisualizationDependencies } from '../plugin'; +import { TimeRange, esFilters, esQuery } from '../../../../../plugins/data/public'; interface Stats { cacheCount: number; @@ -75,7 +73,7 @@ export function getTimelionRequestHandler(dependencies: TimelionVisualizationDep ); } - const esQueryConfigs = getEsQueryConfig(uiSettings); + const esQueryConfigs = esQuery.getEsQueryConfig(uiSettings); // parse the time range client side to make sure it behaves like other charts const timeRangeBounds = timefilter.calculateBounds(timeRange); @@ -86,7 +84,9 @@ export function getTimelionRequestHandler(dependencies: TimelionVisualizationDep sheet: [expression], extended: { es: { - filter: buildEsQuery(undefined, query, filters, esQueryConfigs), + filter: esQuery + // @ts-ignore + .buildEsQuery(null, query, filters, esQueryConfigs), }, }, time: { diff --git a/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/annotations/query.js b/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/annotations/query.js index e91c182ad1d5a69..9c420c84e46018c 100644 --- a/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/annotations/query.js +++ b/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/annotations/query.js @@ -19,7 +19,7 @@ import { getBucketSize } from '../../helpers/get_bucket_size'; import { getTimerange } from '../../helpers/get_timerange'; -import { buildEsQuery } from '@kbn/es-query'; +import { esQuery } from '../../../../../../../../plugins/data/common'; export function query(req, panel, annotation, esQueryConfig, indexPattern, capabilities) { return next => doc => { @@ -30,7 +30,7 @@ export function query(req, panel, annotation, esQueryConfig, indexPattern, capab doc.size = 0; const queries = !annotation.ignore_global_filters ? req.payload.query : []; const filters = !annotation.ignore_global_filters ? req.payload.filters : []; - doc.query = buildEsQuery(indexPattern, queries, filters, esQueryConfig); + doc.query = esQuery.buildEsQuery(indexPattern, queries, filters, esQueryConfig); const timerange = { range: { [timeField]: { @@ -44,12 +44,12 @@ export function query(req, panel, annotation, esQueryConfig, indexPattern, capab if (annotation.query_string) { doc.query.bool.must.push( - buildEsQuery(indexPattern, [annotation.query_string], [], esQueryConfig) + esQuery.buildEsQuery(indexPattern, [annotation.query_string], [], esQueryConfig) ); } if (!annotation.ignore_panel_filters && panel.filter) { - doc.query.bool.must.push(buildEsQuery(indexPattern, [panel.filter], [], esQueryConfig)); + doc.query.bool.must.push(esQuery.buildEsQuery(indexPattern, [panel.filter], [], esQueryConfig)); } if (annotation.fields) { diff --git a/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/query.js b/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/query.js index 75de84ae33462ec..6b1f8db2eb82906 100644 --- a/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/query.js +++ b/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/query.js @@ -19,7 +19,7 @@ import { offsetTime } from '../../offset_time'; import { getIntervalAndTimefield } from '../../get_interval_and_timefield'; -import { buildEsQuery } from '@kbn/es-query'; +import { esQuery } from '../../../../../../../../plugins/data/common'; export function query(req, panel, series, esQueryConfig, indexPatternObject) { return next => doc => { @@ -29,7 +29,7 @@ export function query(req, panel, series, esQueryConfig, indexPatternObject) { doc.size = 0; const queries = !panel.ignore_global_filter ? req.payload.query : []; const filters = !panel.ignore_global_filter ? req.payload.filters : []; - doc.query = buildEsQuery(indexPatternObject, queries, filters, esQueryConfig); + doc.query = esQuery.buildEsQuery(indexPatternObject, queries, filters, esQueryConfig); const timerange = { range: { @@ -43,12 +43,12 @@ export function query(req, panel, series, esQueryConfig, indexPatternObject) { doc.query.bool.must.push(timerange); if (panel.filter) { - doc.query.bool.must.push(buildEsQuery(indexPatternObject, [panel.filter], [], esQueryConfig)); + doc.query.bool.must.push(esQuery.buildEsQuery(indexPatternObject, [panel.filter], [], esQueryConfig)); } if (series.filter) { doc.query.bool.must.push( - buildEsQuery(indexPatternObject, [series.filter], [], esQueryConfig) + esQuery.buildEsQuery(indexPatternObject, [series.filter], [], esQueryConfig) ); } diff --git a/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_filter.js b/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_filter.js index 8b9ebf9319efe62..ab3d6ef2a9302ac 100644 --- a/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_filter.js +++ b/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_filter.js @@ -17,17 +17,21 @@ * under the License. */ -import _ from 'lodash'; -import { buildEsQuery } from '@kbn/es-query'; +import { set } from 'lodash'; +import { esQuery } from '../../../../../../../../plugins/data/common'; export function splitByFilter(req, panel, series, esQueryConfig, indexPattern) { return next => doc => { - if (series.split_mode !== 'filter') return next(doc); - _.set( + if (series.split_mode !== 'filter') { + return next(doc); + } + + set( doc, `aggs.${series.id}.filter`, - buildEsQuery(indexPattern, [series.filter], [], esQueryConfig) + esQuery.buildEsQuery(indexPattern, [series.filter], [], esQueryConfig) ); + return next(doc); }; } diff --git a/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_filters.js b/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_filters.js index 60b29141aaa3ee2..b9cfd941bd68eec 100644 --- a/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_filters.js +++ b/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/series/split_by_filters.js @@ -17,14 +17,16 @@ * under the License. */ -import _ from 'lodash'; -import { buildEsQuery } from '@kbn/es-query'; +import { set } from 'lodash'; +import { esQuery } from '../../../../../../../../plugins/data/common'; + export function splitByFilters(req, panel, series, esQueryConfig, indexPattern) { return next => doc => { if (series.split_mode === 'filters' && series.split_filters) { series.split_filters.forEach(filter => { - const builtEsQuery = buildEsQuery(indexPattern, [filter.filter], [], esQueryConfig); - _.set(doc, `aggs.${series.id}.filters.filters.${filter.id}`, builtEsQuery); + const builtEsQuery = esQuery.buildEsQuery(indexPattern, [filter.filter], [], esQueryConfig); + + set(doc, `aggs.${series.id}.filters.filters.${filter.id}`, builtEsQuery); }); } return next(doc); diff --git a/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/query.js b/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/query.js index 212e7a615dcadc4..d975c9aa65b053a 100644 --- a/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/query.js +++ b/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/query.js @@ -16,9 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -import { buildEsQuery } from '@kbn/es-query'; import { getTimerange } from '../../helpers/get_timerange'; import { getIntervalAndTimefield } from '../../get_interval_and_timefield'; +import { esQuery } from '../../../../../../../../plugins/data/common'; export function query(req, panel, esQueryConfig, indexPatternObject) { return next => doc => { @@ -29,7 +29,7 @@ export function query(req, panel, esQueryConfig, indexPatternObject) { const queries = !panel.ignore_global_filter ? req.payload.query : []; const filters = !panel.ignore_global_filter ? req.payload.filters : []; - doc.query = buildEsQuery(indexPatternObject, queries, filters, esQueryConfig); + doc.query = esQuery.buildEsQuery(indexPatternObject, queries, filters, esQueryConfig); const timerange = { range: { @@ -42,7 +42,7 @@ export function query(req, panel, esQueryConfig, indexPatternObject) { }; doc.query.bool.must.push(timerange); if (panel.filter) { - doc.query.bool.must.push(buildEsQuery(indexPatternObject, [panel.filter], [], esQueryConfig)); + doc.query.bool.must.push(esQuery.buildEsQuery(indexPatternObject, [panel.filter], [], esQueryConfig)); } return next(doc); diff --git a/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/split_by_everything.js b/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/split_by_everything.js index 01d33ca86e6d15c..4361f9a70ccc643 100644 --- a/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/split_by_everything.js +++ b/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/split_by_everything.js @@ -17,21 +17,22 @@ * under the License. */ -import _ from 'lodash'; -import { buildEsQuery } from '@kbn/es-query'; +import { set } from 'lodash'; +import { esQuery } from '../../../../../../../../plugins/data/common'; + export function splitByEverything(req, panel, esQueryConfig, indexPattern) { return next => doc => { panel.series .filter(c => !(c.aggregate_by && c.aggregate_function)) .forEach(column => { if (column.filter) { - _.set( + set( doc, `aggs.pivot.aggs.${column.id}.filter`, - buildEsQuery(indexPattern, [column.filter], [], esQueryConfig) + esQuery.buildEsQuery(indexPattern, [column.filter], [], esQueryConfig) ); } else { - _.set(doc, `aggs.pivot.aggs.${column.id}.filter.match_all`, {}); + set(doc, `aggs.pivot.aggs.${column.id}.filter.match_all`, {}); } }); return next(doc); diff --git a/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/split_by_terms.js b/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/split_by_terms.js index 829f7d8c5a0de77..978b9fdc9579691 100644 --- a/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/split_by_terms.js +++ b/src/legacy/core_plugins/vis_type_timeseries/server/lib/vis_data/request_processors/table/split_by_terms.js @@ -17,20 +17,22 @@ * under the License. */ -import _ from 'lodash'; -import { buildEsQuery } from '@kbn/es-query'; +import { set } from 'lodash'; +import { esQuery } from '../../../../../../../../plugins/data/common'; + export function splitByTerms(req, panel, esQueryConfig, indexPattern) { return next => doc => { panel.series .filter(c => c.aggregate_by && c.aggregate_function) .forEach(column => { - _.set(doc, `aggs.pivot.aggs.${column.id}.terms.field`, column.aggregate_by); - _.set(doc, `aggs.pivot.aggs.${column.id}.terms.size`, 100); + set(doc, `aggs.pivot.aggs.${column.id}.terms.field`, column.aggregate_by); + set(doc, `aggs.pivot.aggs.${column.id}.terms.size`, 100); + if (column.filter) { - _.set( + set( doc, `aggs.pivot.aggs.${column.id}.column_filter.filter`, - buildEsQuery(indexPattern, [column.filter], [], esQueryConfig) + esQuery.buildEsQuery(indexPattern, [column.filter], [], esQueryConfig) ); } }); diff --git a/src/legacy/core_plugins/vis_type_vega/public/vega_request_handler.ts b/src/legacy/core_plugins/vis_type_vega/public/vega_request_handler.ts index b4c32f37eb90c12..de8284d43bd4220 100644 --- a/src/legacy/core_plugins/vis_type_vega/public/vega_request_handler.ts +++ b/src/legacy/core_plugins/vis_type_vega/public/vega_request_handler.ts @@ -20,9 +20,7 @@ import { timefilter } from 'ui/timefilter'; import { TimeRange } from 'src/plugins/data/public'; import { Query } from 'src/legacy/core_plugins/data/public'; -import { buildEsQuery, getEsQueryConfig } from '@kbn/es-query'; - -import { esFilters } from '../../../../plugins/data/public'; +import { esFilters, esQuery } from '../../../../plugins/data/public'; // @ts-ignore import { VegaParser } from './data_model/vega_parser'; @@ -52,8 +50,8 @@ export function createVegaRequestHandler({ return ({ timeRange, filters, query, visParams }: VegaRequestHandlerParams) => { timeCache.setTimeRange(timeRange); - const esQueryConfigs = getEsQueryConfig(uiSettings); - const filtersDsl = buildEsQuery(undefined, query, filters, esQueryConfigs); + const esQueryConfigs = esQuery.getEsQueryConfig(uiSettings); + const filtersDsl = esQuery.buildEsQuery(null, query, filters, esQueryConfigs); const vp = new VegaParser(visParams.spec, searchCache, timeCache, filtersDsl, serviceSettings); return vp.parseAsync(); diff --git a/src/legacy/ui/public/agg_types/buckets/_terms_other_bucket_helper.js b/src/legacy/ui/public/agg_types/buckets/_terms_other_bucket_helper.js index 70bca2e40ae3fa9..d0d712704964be8 100644 --- a/src/legacy/ui/public/agg_types/buckets/_terms_other_bucket_helper.js +++ b/src/legacy/ui/public/agg_types/buckets/_terms_other_bucket_helper.js @@ -18,9 +18,8 @@ */ import _ from 'lodash'; -import { buildQueryFromFilters } from '@kbn/es-query'; import { AggGroupNames } from '../../vis/editors/default/agg_groups'; -import { esFilters } from '../../../../../plugins/data/public'; +import { esFilters, esQuery } from '../../../../../plugins/data/public'; /** * walks the aggregation DSL and returns DSL starting at aggregation with id of startFromAggId @@ -197,7 +196,7 @@ export const buildOtherBucketAgg = (aggConfigs, aggWithOtherBucket, response) => }); resultAgg.filters.filters[key] = { - bool: buildQueryFromFilters(filters, indexPattern), + bool: esQuery.buildQueryFromFilters(filters, indexPattern), }; }; walkBucketTree(0, response.aggregations, bucketAggs[0].id, [], ''); diff --git a/src/legacy/ui/public/agg_types/buckets/filters.ts b/src/legacy/ui/public/agg_types/buckets/filters.ts index 44a97abb7a1d775..d59b4e772105408 100644 --- a/src/legacy/ui/public/agg_types/buckets/filters.ts +++ b/src/legacy/ui/public/agg_types/buckets/filters.ts @@ -23,12 +23,12 @@ import angular from 'angular'; import { i18n } from '@kbn/i18n'; import chrome from 'ui/chrome'; -import { buildEsQuery } from '@kbn/es-query'; import { FiltersParamEditor, FilterValue } from '../../vis/editors/default/controls/filters'; import { createFilterFilters } from './create_filter/filters'; import { BucketAggType, IBucketAggConfig } from './_bucket_agg_type'; import { setup as data } from '../../../../core_plugins/data/public/legacy'; import { Storage } from '../../../../../plugins/kibana_utils/public'; +import { esQuery } from '../../../../../plugins/data/public'; const { getQueryLog } = data.query.helpers; const config = chrome.getUiSettingsClient(); @@ -69,7 +69,7 @@ export const filtersBucketAgg = new BucketAggType({ return; } - const query = buildEsQuery(aggConfig.getIndexPattern(), [input], [], config); + const query = esQuery.buildEsQuery(aggConfig.getIndexPattern(), [input], [], config); if (!query) { console.log('malformed filter agg params, missing "query" on input'); // eslint-disable-line no-console diff --git a/src/legacy/ui/public/courier/search_source/search_source.js b/src/legacy/ui/public/courier/search_source/search_source.js index 729de41ed77db58..bc69e862fea4873 100644 --- a/src/legacy/ui/public/courier/search_source/search_source.js +++ b/src/legacy/ui/public/courier/search_source/search_source.js @@ -71,13 +71,12 @@ import _ from 'lodash'; import angular from 'angular'; -import { getEsQueryConfig, buildEsQuery } from '@kbn/es-query'; import { normalizeSortRequest } from './_normalize_sort_request'; import { fetchSoon } from '../fetch'; import { fieldWildcardFilter } from '../../field_wildcard'; -import { getHighlightRequest } from '../../../../../plugins/data/public'; +import { getHighlightRequest, esQuery } from '../../../../../plugins/data/public'; import { npSetup } from 'ui/new_platform'; import chrome from '../../chrome'; import { RequestFailure } from '../fetch/errors'; @@ -491,8 +490,8 @@ export class SearchSource { _.set(flatData.body, '_source.includes', remainingFields); } - const esQueryConfigs = getEsQueryConfig(config); - flatData.body.query = buildEsQuery(flatData.index, flatData.query, flatData.filters, esQueryConfigs); + const esQueryConfigs = esQuery.getEsQueryConfig(config); + flatData.body.query = esQuery.buildEsQuery(flatData.index, flatData.query, flatData.filters, esQueryConfigs); if (flatData.highlightAll != null) { if (flatData.highlightAll && flatData.body.query) { diff --git a/src/plugins/data/common/es_query/__tests__/fields_mock.ts b/src/plugins/data/common/es_query/__tests__/fields_mock.ts index 83fdf588af00c8d..400b42002b0a867 100644 --- a/src/plugins/data/common/es_query/__tests__/fields_mock.ts +++ b/src/plugins/data/common/es_query/__tests__/fields_mock.ts @@ -16,8 +16,9 @@ * specific language governing permissions and limitations * under the License. */ +import { IFieldType } from '../../fields'; -export const fields = [ +export const fields: IFieldType[] = [ { name: 'bytes', type: 'number', @@ -317,4 +318,4 @@ export const fields = [ }, ]; -export const getField = (name: string) => fields.find(field => field.name === name); +export const getField = (name: string) => fields.find(field => field.name === name) as IFieldType; diff --git a/packages/kbn-es-query/src/es_query/__tests__/build_es_query.js b/src/plugins/data/common/es_query/es_query/build_es_query.test.ts similarity index 61% rename from packages/kbn-es-query/src/es_query/__tests__/build_es_query.js rename to src/plugins/data/common/es_query/es_query/build_es_query.test.ts index fde3d063caaa6e5..06662669ac37725 100644 --- a/packages/kbn-es-query/src/es_query/__tests__/build_es_query.js +++ b/src/plugins/data/common/es_query/es_query/build_es_query.test.ts @@ -17,99 +17,100 @@ * under the License. */ -import expect from '@kbn/expect'; -import { buildEsQuery } from '../build_es_query'; -import indexPattern from '../../__fixtures__/index_pattern_response.json'; -import { fromKueryExpression, toElasticsearchQuery } from '../../kuery'; -import { luceneStringToDsl } from '../lucene_string_to_dsl'; -import { decorateQuery } from '../decorate_query'; +import { buildEsQuery } from './build_es_query'; +import { fromKueryExpression, toElasticsearchQuery } from '@kbn/es-query'; +import { luceneStringToDsl } from './lucene_string_to_dsl'; +import { decorateQuery } from './decorate_query'; +import { IIndexPattern } from '../../index_patterns'; +import { MatchAllFilter } from '../filters'; +import { fields } from '../__tests__/fields_mock'; +import { Query } from '../../query/types'; -describe('build query', function () { - describe('buildEsQuery', function () { +describe('build query', () => { + const indexPattern: IIndexPattern = ({ + fields, + } as unknown) as IIndexPattern; - it('should return the parameters of an Elasticsearch bool query', function () { - const result = buildEsQuery(); + describe('buildEsQuery', () => { + it('should return the parameters of an Elasticsearch bool query', () => { + const result = buildEsQuery(indexPattern, [], []); const expected = { bool: { must: [], filter: [], should: [], must_not: [], - } + }, }; - expect(result).to.eql(expected); + expect(result).toEqual(expected); }); - it('should combine queries and filters from multiple query languages into a single ES bool query', function () { + it('should combine queries and filters from multiple query languages into a single ES bool query', () => { const queries = [ { query: 'extension:jpg', language: 'kuery' }, { query: 'bar:baz', language: 'lucene' }, - ]; + ] as Query[]; const filters = [ { match_all: {}, meta: { type: 'match_all' }, - }, + } as MatchAllFilter, ]; const config = { allowLeadingWildcards: true, queryStringOptions: {}, + ignoreFilterIfFieldNotInIndex: false, }; const expectedResult = { bool: { - must: [ - decorateQuery(luceneStringToDsl('bar:baz'), config.queryStringOptions), - ], + must: [decorateQuery(luceneStringToDsl('bar:baz'), config.queryStringOptions)], filter: [ toElasticsearchQuery(fromKueryExpression('extension:jpg'), indexPattern), { match_all: {} }, ], should: [], must_not: [], - } + }, }; const result = buildEsQuery(indexPattern, queries, filters, config); - expect(result).to.eql(expectedResult); + expect(result).toEqual(expectedResult); }); - it('should accept queries and filters as either single objects or arrays', function () { - const queries = { query: 'extension:jpg', language: 'lucene' }; + it('should accept queries and filters as either single objects or arrays', () => { + const queries = { query: 'extension:jpg', language: 'lucene' } as Query; const filters = { match_all: {}, meta: { type: 'match_all' }, - }; + } as MatchAllFilter; const config = { allowLeadingWildcards: true, queryStringOptions: {}, + ignoreFilterIfFieldNotInIndex: false, }; const expectedResult = { bool: { - must: [ - decorateQuery(luceneStringToDsl('extension:jpg'), config.queryStringOptions), - ], + must: [decorateQuery(luceneStringToDsl('extension:jpg'), config.queryStringOptions)], filter: [{ match_all: {} }], should: [], must_not: [], - } + }, }; const result = buildEsQuery(indexPattern, queries, filters, config); - expect(result).to.eql(expectedResult); + expect(result).toEqual(expectedResult); }); - it('should use the default time zone set in the Advanced Settings in queries and filters', function () { + it('should use the default time zone set in the Advanced Settings in queries and filters', () => { const queries = [ { query: '@timestamp:"2019-03-23T13:18:00"', language: 'kuery' }, - { query: '@timestamp:"2019-03-23T13:18:00"', language: 'lucene' } - ]; - const filters = [ - { match_all: {}, meta: { type: 'match_all' } } - ]; + { query: '@timestamp:"2019-03-23T13:18:00"', language: 'lucene' }, + ] as Query[]; + const filters = [{ match_all: {}, meta: { type: 'match_all' } } as MatchAllFilter]; const config = { allowLeadingWildcards: true, queryStringOptions: {}, @@ -120,20 +121,27 @@ describe('build query', function () { const expectedResult = { bool: { must: [ - decorateQuery(luceneStringToDsl('@timestamp:"2019-03-23T13:18:00"'), config.queryStringOptions, config.dateFormatTZ), + decorateQuery( + luceneStringToDsl('@timestamp:"2019-03-23T13:18:00"'), + config.queryStringOptions, + config.dateFormatTZ + ), ], filter: [ - toElasticsearchQuery(fromKueryExpression('@timestamp:"2019-03-23T13:18:00"'), indexPattern, config), - { match_all: {} } + toElasticsearchQuery( + fromKueryExpression('@timestamp:"2019-03-23T13:18:00"'), + indexPattern, + config + ), + { match_all: {} }, ], should: [], must_not: [], - } + }, }; const result = buildEsQuery(indexPattern, queries, filters, config); - expect(result).to.eql(expectedResult); - }); + expect(result).toEqual(expectedResult); + }); }); - }); diff --git a/packages/kbn-es-query/src/es_query/build_es_query.js b/src/plugins/data/common/es_query/es_query/build_es_query.ts similarity index 58% rename from packages/kbn-es-query/src/es_query/build_es_query.js rename to src/plugins/data/common/es_query/es_query/build_es_query.ts index d17147761d8bcd5..b75449679366037 100644 --- a/packages/kbn-es-query/src/es_query/build_es_query.js +++ b/src/plugins/data/common/es_query/es_query/build_es_query.ts @@ -21,6 +21,16 @@ import { groupBy, has } from 'lodash'; import { buildQueryFromKuery } from './from_kuery'; import { buildQueryFromFilters } from './from_filters'; import { buildQueryFromLucene } from './from_lucene'; +import { IIndexPattern } from '../../index_patterns'; +import { Filter } from '../filters'; +import { Query } from '../../query/types'; + +export interface EsQueryConfig { + allowLeadingWildcards: boolean; + queryStringOptions: Record; + ignoreFilterIfFieldNotInIndex: boolean; + dateFormatTZ?: string; +} /** * @param indexPattern @@ -31,30 +41,43 @@ import { buildQueryFromLucene } from './from_lucene'; * config contains dateformat:tz */ export function buildEsQuery( - indexPattern, - queries = [], - filters = [], - config = { + indexPattern: IIndexPattern | null, + queries: Query | Query[], + filters: Filter | Filter[], + config: EsQueryConfig = { allowLeadingWildcards: false, queryStringOptions: {}, ignoreFilterIfFieldNotInIndex: false, - dateFormatTZ: null, - }) { + } +) { queries = Array.isArray(queries) ? queries : [queries]; filters = Array.isArray(filters) ? filters : [filters]; - const validQueries = queries.filter((query) => has(query, 'query')); + const validQueries = queries.filter(query => has(query, 'query')); const queriesByLanguage = groupBy(validQueries, 'language'); - const kueryQuery = buildQueryFromKuery(indexPattern, queriesByLanguage.kuery, config.allowLeadingWildcards, config.dateFormatTZ); - const luceneQuery = buildQueryFromLucene(queriesByLanguage.lucene, config.queryStringOptions, config.dateFormatTZ); - const filterQuery = buildQueryFromFilters(filters, indexPattern, config.ignoreFilterIfFieldNotInIndex); + const kueryQuery = buildQueryFromKuery( + indexPattern, + queriesByLanguage.kuery, + config.allowLeadingWildcards, + config.dateFormatTZ + ); + const luceneQuery = buildQueryFromLucene( + queriesByLanguage.lucene, + config.queryStringOptions, + config.dateFormatTZ + ); + const filterQuery = buildQueryFromFilters( + filters, + indexPattern, + config.ignoreFilterIfFieldNotInIndex + ); return { bool: { - must: [].concat(kueryQuery.must, luceneQuery.must, filterQuery.must), - filter: [].concat(kueryQuery.filter, luceneQuery.filter, filterQuery.filter), - should: [].concat(kueryQuery.should, luceneQuery.should, filterQuery.should), - must_not: [].concat(kueryQuery.must_not, luceneQuery.must_not, filterQuery.must_not), - } + must: [...kueryQuery.must, ...luceneQuery.must, ...filterQuery.must], + filter: [...kueryQuery.filter, ...luceneQuery.filter, ...filterQuery.filter], + should: [...kueryQuery.should, ...luceneQuery.should, ...filterQuery.should], + must_not: [...kueryQuery.must_not, ...luceneQuery.must_not, ...filterQuery.must_not], + }, }; } diff --git a/packages/kbn-es-query/src/es_query/__tests__/decorate_query.js b/src/plugins/data/common/es_query/es_query/decorate_query.test.ts similarity index 50% rename from packages/kbn-es-query/src/es_query/__tests__/decorate_query.js rename to src/plugins/data/common/es_query/es_query/decorate_query.test.ts index d5978716dac9e21..d7cd82eb7108a36 100644 --- a/packages/kbn-es-query/src/es_query/__tests__/decorate_query.js +++ b/src/plugins/data/common/es_query/es_query/decorate_query.test.ts @@ -17,21 +17,30 @@ * under the License. */ -import expect from '@kbn/expect'; -import { decorateQuery } from '../decorate_query'; +import { decorateQuery } from './decorate_query'; -describe('Query decorator', function () { - it('should be a function', function () { - expect(decorateQuery).to.be.a(Function); +describe('Query decorator', () => { + test('should be a function', () => { + expect(typeof decorateQuery).toBe('function'); }); - it('should merge in the query string options', function () { - const decoratedQuery = decorateQuery({ query_string: { query: '*' } }, { analyze_wildcard: true }); - expect(decoratedQuery).to.eql({ query_string: { query: '*', analyze_wildcard: true } }); + test('should merge in the query string options', () => { + const decoratedQuery = decorateQuery( + { query_string: { query: '*' } }, + { analyze_wildcard: true } + ); + + expect(decoratedQuery).toEqual({ query_string: { query: '*', analyze_wildcard: true } }); }); - it('should add a default of a time_zone parameter if one is provided', function () { - const decoratedQuery = decorateQuery({ query_string: { query: '*' } }, { analyze_wildcard: true }, 'America/Phoenix'); - expect(decoratedQuery).to.eql({ query_string: { query: '*', analyze_wildcard: true, time_zone: 'America/Phoenix' } }); + test('should add a default of a time_zone parameter if one is provided', () => { + const decoratedQuery = decorateQuery( + { query_string: { query: '*' } }, + { analyze_wildcard: true }, + 'America/Phoenix' + ); + expect(decoratedQuery).toEqual({ + query_string: { query: '*', analyze_wildcard: true, time_zone: 'America/Phoenix' }, + }); }); }); diff --git a/packages/kbn-es-query/src/es_query/decorate_query.js b/src/plugins/data/common/es_query/es_query/decorate_query.ts similarity index 69% rename from packages/kbn-es-query/src/es_query/decorate_query.js rename to src/plugins/data/common/es_query/es_query/decorate_query.ts index 8104707e0298a54..891712d057886ca 100644 --- a/packages/kbn-es-query/src/es_query/decorate_query.js +++ b/src/plugins/data/common/es_query/es_query/decorate_query.ts @@ -17,8 +17,9 @@ * under the License. */ -import _ from 'lodash'; -import { getTimeZoneFromSettings } from '../utils/get_time_zone_from_settings'; +import { extend, defaults } from 'lodash'; +import { getTimeZoneFromSettings } from '../utils'; +import { DslQuery, isEsQueryString } from './es_query_dsl'; /** * Decorate queries with default parameters @@ -28,11 +29,17 @@ import { getTimeZoneFromSettings } from '../utils/get_time_zone_from_settings'; * @returns {object} */ -export function decorateQuery(query, queryStringOptions, dateFormatTZ = null) { - if (_.has(query, 'query_string.query')) { - _.extend(query.query_string, queryStringOptions); +export function decorateQuery( + query: DslQuery, + queryStringOptions: Record, + dateFormatTZ?: string +) { + if (isEsQueryString(query)) { + extend(query.query_string, queryStringOptions); if (dateFormatTZ) { - _.defaults(query.query_string, { time_zone: getTimeZoneFromSettings(dateFormatTZ) }); + defaults(query.query_string, { + time_zone: getTimeZoneFromSettings(dateFormatTZ), + }); } } diff --git a/src/plugins/data/common/es_query/es_query/es_query_dsl.ts b/src/plugins/data/common/es_query/es_query/es_query_dsl.ts new file mode 100644 index 000000000000000..d906ae5359ec20b --- /dev/null +++ b/src/plugins/data/common/es_query/es_query/es_query_dsl.ts @@ -0,0 +1,65 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { has } from 'lodash'; + +export interface DslRangeQuery { + range: { + [name: string]: { + gte: number; + lte: number; + format: string; + }; + }; +} + +export interface DslMatchQuery { + match: { + [name: string]: { + query: string; + operator: string; + zero_terms_query: string; + }; + }; +} + +export interface DslQueryStringQuery { + query_string: { + query: string; + analyze_wildcard?: boolean; + }; +} + +export interface DslMatchAllQuery { + match_all: Record; +} + +export interface DslTermQuery { + term: Record; +} + +export type DslQuery = + | DslRangeQuery + | DslMatchQuery + | DslQueryStringQuery + | DslMatchAllQuery + | DslTermQuery; + +export const isEsQueryString = (query: any): query is DslQueryStringQuery => + has(query, 'query_string.query'); diff --git a/packages/kbn-es-query/src/es_query/__tests__/filter_matches_index.js b/src/plugins/data/common/es_query/es_query/filter_matches_index.test.ts similarity index 62% rename from packages/kbn-es-query/src/es_query/__tests__/filter_matches_index.js rename to src/plugins/data/common/es_query/es_query/filter_matches_index.test.ts index 1c43230aeea3048..6a5c7bdf8eea3d9 100644 --- a/packages/kbn-es-query/src/es_query/__tests__/filter_matches_index.js +++ b/src/plugins/data/common/es_query/es_query/filter_matches_index.test.ts @@ -17,31 +17,36 @@ * under the License. */ -import expect from '@kbn/expect'; -import { filterMatchesIndex } from '../filter_matches_index'; +import { Filter } from '../filters'; +import { filterMatchesIndex } from './filter_matches_index'; +import { IIndexPattern } from '../../index_patterns'; -describe('filterMatchesIndex', function () { +describe('filterMatchesIndex', () => { it('should return true if the filter has no meta', () => { - const filter = {}; - const indexPattern = { id: 'foo', fields: [{ name: 'bar' }] }; - expect(filterMatchesIndex(filter, indexPattern)).to.be(true); + const filter = {} as Filter; + const indexPattern = { id: 'foo', fields: [{ name: 'bar' }] } as IIndexPattern; + + expect(filterMatchesIndex(filter, indexPattern)).toBe(true); }); it('should return true if no index pattern is passed', () => { - const filter = { meta: { index: 'foo', key: 'bar' } }; - const indexPattern = undefined; - expect(filterMatchesIndex(filter, indexPattern)).to.be(true); + const filter = { meta: { index: 'foo', key: 'bar' } } as Filter; + const indexPattern = null; + + expect(filterMatchesIndex(filter, indexPattern)).toBe(true); }); it('should return true if the filter key matches a field name', () => { - const filter = { meta: { index: 'foo', key: 'bar' } }; - const indexPattern = { id: 'foo', fields: [{ name: 'bar' }] }; - expect(filterMatchesIndex(filter, indexPattern)).to.be(true); + const filter = { meta: { index: 'foo', key: 'bar' } } as Filter; + const indexPattern = { id: 'foo', fields: [{ name: 'bar' }] } as IIndexPattern; + + expect(filterMatchesIndex(filter, indexPattern)).toBe(true); }); it('should return false if the filter key does not match a field name', () => { - const filter = { meta: { index: 'foo', key: 'baz' } }; - const indexPattern = { id: 'foo', fields: [{ name: 'bar' }] }; - expect(filterMatchesIndex(filter, indexPattern)).to.be(false); + const filter = { meta: { index: 'foo', key: 'baz' } } as Filter; + const indexPattern = { id: 'foo', fields: [{ name: 'bar' }] } as IIndexPattern; + + expect(filterMatchesIndex(filter, indexPattern)).toBe(false); }); }); diff --git a/packages/kbn-es-query/src/es_query/index.d.ts b/src/plugins/data/common/es_query/es_query/filter_matches_index.ts similarity index 57% rename from packages/kbn-es-query/src/es_query/index.d.ts rename to src/plugins/data/common/es_query/es_query/filter_matches_index.ts index 9510a18441e53cc..e04cdecf7f40c14 100644 --- a/packages/kbn-es-query/src/es_query/index.d.ts +++ b/src/plugins/data/common/es_query/es_query/filter_matches_index.ts @@ -17,23 +17,18 @@ * under the License. */ -export function buildQueryFromFilters(filters: unknown[], indexPattern: unknown): unknown; -export function buildEsQuery( - indexPattern: unknown, - queries: unknown, - filters: unknown, - config?: { - allowLeadingWildcards: boolean; - queryStringOptions: unknown; - ignoreFilterIfFieldNotInIndex: boolean; - dateFormatTZ?: string | null; +import { IIndexPattern } from '../../index_patterns'; +import { IFieldType } from '../../fields'; +import { Filter } from '../filters'; + +/* + * TODO: We should base this on something better than `filter.meta.key`. We should probably modify + * this to check if `filter.meta.index` matches `indexPattern.id` instead, but that's a breaking + * change. + */ +export function filterMatchesIndex(filter: Filter, indexPattern: IIndexPattern | null) { + if (!filter.meta || !indexPattern) { + return true; } -): unknown; -export function getEsQueryConfig(config: { - get: (name: string) => unknown; -}): { - allowLeadingWildcards: boolean; - queryStringOptions: unknown; - ignoreFilterIfFieldNotInIndex: boolean; - dateFormatTZ?: string | null; -}; + return indexPattern.fields.some((field: IFieldType) => field.name === filter.meta.key); +} diff --git a/src/plugins/data/common/es_query/es_query/from_filters.test.ts b/src/plugins/data/common/es_query/es_query/from_filters.test.ts new file mode 100644 index 000000000000000..7df6b0f1ff8cb74 --- /dev/null +++ b/src/plugins/data/common/es_query/es_query/from_filters.test.ts @@ -0,0 +1,148 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { buildQueryFromFilters } from './from_filters'; +import { IIndexPattern } from '../../index_patterns'; +import { ExistsFilter, Filter, MatchAllFilter } from '../filters'; +import { fields } from '../__tests__/fields_mock'; + +describe('build query', () => { + const indexPattern: IIndexPattern = ({ + fields, + } as unknown) as IIndexPattern; + + describe('buildQueryFromFilters', () => { + test('should return the parameters of an Elasticsearch bool query', () => { + const result = buildQueryFromFilters([], indexPattern, false); + const expected = { + must: [], + filter: [], + should: [], + must_not: [], + }; + expect(result).toEqual(expected); + }); + + test('should transform an array of kibana filters into ES queries combined in the bool clauses', () => { + const filters = [ + { + match_all: {}, + meta: { type: 'match_all' }, + } as MatchAllFilter, + { + exists: { field: 'foo' }, + meta: { type: 'exists' }, + } as ExistsFilter, + ] as Filter[]; + + const expectedESQueries = [{ match_all: {} }, { exists: { field: 'foo' } }]; + + const result = buildQueryFromFilters(filters, indexPattern, false); + + expect(result.filter).toEqual(expectedESQueries); + }); + + test('should remove disabled filters', () => { + const filters = [ + { + match_all: {}, + meta: { type: 'match_all', negate: true, disabled: true }, + } as MatchAllFilter, + ] as Filter[]; + const result = buildQueryFromFilters(filters, indexPattern, false); + + expect(result.must_not).toEqual([]); + }); + + test('should remove falsy filters', () => { + const filters = ([null, undefined] as unknown) as Filter[]; + const result = buildQueryFromFilters(filters, indexPattern, false); + + expect(result.must_not).toEqual([]); + expect(result.must).toEqual([]); + }); + + test('should place negated filters in the must_not clause', () => { + const filters = [ + { + match_all: {}, + meta: { type: 'match_all', negate: true }, + } as MatchAllFilter, + ] as Filter[]; + + const expectedESQueries = [{ match_all: {} }]; + + const result = buildQueryFromFilters(filters, indexPattern, false); + + expect(result.must_not).toEqual(expectedESQueries); + }); + + test('should translate old ES filter syntax into ES 5+ query objects', () => { + const filters = [ + { + query: { exists: { field: 'foo' } }, + meta: { type: 'exists' }, + }, + ] as Filter[]; + + const expectedESQueries = [ + { + exists: { field: 'foo' }, + }, + ]; + + const result = buildQueryFromFilters(filters, indexPattern, false); + + expect(result.filter).toEqual(expectedESQueries); + }); + + test('should migrate deprecated match syntax', () => { + const filters = [ + { + query: { match: { extension: { query: 'foo', type: 'phrase' } } }, + meta: { type: 'phrase' }, + }, + ] as Filter[]; + + const expectedESQueries = [ + { + match_phrase: { extension: { query: 'foo' } }, + }, + ]; + + const result = buildQueryFromFilters(filters, indexPattern, false); + + expect(result.filter).toEqual(expectedESQueries); + }); + + test('should not add query:queryString:options to query_string filters', () => { + const filters = [ + { + query: { query_string: { query: 'foo' } }, + meta: { type: 'query_string' }, + }, + ] as Filter[]; + + const expectedESQueries = [{ query_string: { query: 'foo' } }]; + const result = buildQueryFromFilters(filters, indexPattern, false); + + expect(result.filter).toEqual(expectedESQueries); + }); + }); +}); diff --git a/packages/kbn-es-query/src/es_query/from_filters.js b/src/plugins/data/common/es_query/es_query/from_filters.ts similarity index 69% rename from packages/kbn-es-query/src/es_query/from_filters.js rename to src/plugins/data/common/es_query/es_query/from_filters.ts index 10f9cf82fc9721b..1e0957d81659084 100644 --- a/packages/kbn-es-query/src/es_query/from_filters.js +++ b/src/plugins/data/common/es_query/es_query/from_filters.ts @@ -16,10 +16,11 @@ * specific language governing permissions and limitations * under the License. */ - -import _ from 'lodash'; +import { isUndefined } from 'lodash'; import { migrateFilter } from './migrate_filter'; import { filterMatchesIndex } from './filter_matches_index'; +import { Filter, cleanFilter, isFilterDisabled } from '../filters'; +import { IIndexPattern } from '../../index_patterns'; /** * Create a filter that can be reversed for filters with negate set @@ -28,11 +29,12 @@ import { filterMatchesIndex } from './filter_matches_index'; * through otherwise it will filter out * @returns {function} */ -const filterNegate = function (reverse) { - return function (filter) { - if (_.isUndefined(filter.meta) || _.isUndefined(filter.meta.negate)) return !reverse; - return filter.meta && filter.meta.negate === reverse; - }; +const filterNegate = (reverse: boolean) => (filter: Filter) => { + if (isUndefined(filter.meta) || isUndefined(filter.meta.negate)) { + return !reverse; + } + + return filter.meta && filter.meta.negate === reverse; }; /** @@ -40,7 +42,7 @@ const filterNegate = function (reverse) { * @param {Object} filter - The filter to translate * @return {Object} the query version of that filter */ -const translateToQuery = function (filter) { +const translateToQuery = (filter: Filter) => { if (!filter) return; if (filter.query) { @@ -50,17 +52,13 @@ const translateToQuery = function (filter) { return filter; }; -/** - * Clean out any invalid attributes from the filters - * @param {object} filter The filter to clean - * @returns {object} - */ -const cleanFilter = function (filter) { - return _.omit(filter, ['meta', '$state']); -}; +export const buildQueryFromFilters = ( + filters: Filter[] = [], + indexPattern: IIndexPattern | null, + ignoreFilterIfFieldNotInIndex: boolean = false +) => { + filters = filters.filter(filter => filter && !isFilterDisabled(filter)); -export function buildQueryFromFilters(filters = [], indexPattern, ignoreFilterIfFieldNotInIndex) { - filters = filters.filter(filter => filter && !_.get(filter, ['meta', 'disabled'])); return { must: [], filter: filters @@ -68,17 +66,13 @@ export function buildQueryFromFilters(filters = [], indexPattern, ignoreFilterIf .filter(filter => !ignoreFilterIfFieldNotInIndex || filterMatchesIndex(filter, indexPattern)) .map(translateToQuery) .map(cleanFilter) - .map(filter => { - return migrateFilter(filter, indexPattern); - }), + .map(filter => migrateFilter(filter, indexPattern)), should: [], must_not: filters .filter(filterNegate(true)) .filter(filter => !ignoreFilterIfFieldNotInIndex || filterMatchesIndex(filter, indexPattern)) .map(translateToQuery) .map(cleanFilter) - .map(filter => { - return migrateFilter(filter, indexPattern); - }), + .map(filter => migrateFilter(filter, indexPattern)), }; -} +}; diff --git a/packages/kbn-es-query/src/es_query/__tests__/from_kuery.js b/src/plugins/data/common/es_query/es_query/from_kuery.test.ts similarity index 54% rename from packages/kbn-es-query/src/es_query/__tests__/from_kuery.js rename to src/plugins/data/common/es_query/es_query/from_kuery.test.ts index 18738b05ea69d43..1cd96c63c7bd7dd 100644 --- a/packages/kbn-es-query/src/es_query/__tests__/from_kuery.js +++ b/src/plugins/data/common/es_query/es_query/from_kuery.test.ts @@ -17,14 +17,19 @@ * under the License. */ -import { buildQueryFromKuery } from '../from_kuery'; -import indexPattern from '../../__fixtures__/index_pattern_response.json'; -import expect from '@kbn/expect'; -import { fromKueryExpression, toElasticsearchQuery } from '../../kuery'; - -describe('build query', function () { - describe('buildQueryFromKuery', function () { - it('should return the parameters of an Elasticsearch bool query', function () { +import { buildQueryFromKuery } from './from_kuery'; +import { fromKueryExpression, toElasticsearchQuery } from '@kbn/es-query'; +import { IIndexPattern } from '../../index_patterns'; +import { fields } from '../__tests__/fields_mock'; +import { Query } from '../../query/types'; + +describe('build query', () => { + const indexPattern: IIndexPattern = ({ + fields, + } as unknown) as IIndexPattern; + + describe('buildQueryFromKuery', () => { + test('should return the parameters of an Elasticsearch bool query', () => { const result = buildQueryFromKuery(null, [], true); const expected = { must: [], @@ -32,50 +37,48 @@ describe('build query', function () { should: [], must_not: [], }; - expect(result).to.eql(expected); + expect(result).toEqual(expected); }); - it('should transform an array of kuery queries into ES queries combined in the bool\'s filter clause', function () { + test("should transform an array of kuery queries into ES queries combined in the bool's filter clause", () => { const queries = [ { query: 'extension:jpg', language: 'kuery' }, { query: 'machine.os:osx', language: 'kuery' }, - ]; + ] as Query[]; - const expectedESQueries = queries.map( - (query) => { - return toElasticsearchQuery(fromKueryExpression(query.query), indexPattern); - } - ); + const expectedESQueries = queries.map(query => { + return toElasticsearchQuery(fromKueryExpression(query.query), indexPattern); + }); const result = buildQueryFromKuery(indexPattern, queries, true); - expect(result.filter).to.eql(expectedESQueries); + expect(result.filter).toEqual(expectedESQueries); }); - it('should accept a specific date format for a kuery query into an ES query in the bool\'s filter clause', function () { - const queries = [{ query: '@timestamp:"2018-04-03T19:04:17"', language: 'kuery' }]; - + test("should accept a specific date format for a kuery query into an ES query in the bool's filter clause", () => { + const queries = [{ query: '@timestamp:"2018-04-03T19:04:17"', language: 'kuery' }] as Query[]; const expectedESQueries = queries.map(query => { - return toElasticsearchQuery(fromKueryExpression(query.query), indexPattern, { dateFormatTZ: 'America/Phoenix' }); + return toElasticsearchQuery(fromKueryExpression(query.query), indexPattern, { + dateFormatTZ: 'America/Phoenix', + }); }); const result = buildQueryFromKuery(indexPattern, queries, true, 'America/Phoenix'); - expect(result.filter).to.eql(expectedESQueries); + expect(result.filter).toEqual(expectedESQueries); }); - it('should gracefully handle date queries when no date format is provided', function () { - const queries = [{ query: '@timestamp:"2018-04-03T19:04:17Z"', language: 'kuery' }]; - + test('should gracefully handle date queries when no date format is provided', () => { + const queries = [ + { query: '@timestamp:"2018-04-03T19:04:17Z"', language: 'kuery' }, + ] as Query[]; const expectedESQueries = queries.map(query => { return toElasticsearchQuery(fromKueryExpression(query.query), indexPattern); }); const result = buildQueryFromKuery(indexPattern, queries, true); - expect(result.filter).to.eql(expectedESQueries); + expect(result.filter).toEqual(expectedESQueries); }); - }); - }); diff --git a/packages/kbn-es-query/src/es_query/from_kuery.js b/src/plugins/data/common/es_query/es_query/from_kuery.ts similarity index 60% rename from packages/kbn-es-query/src/es_query/from_kuery.js rename to src/plugins/data/common/es_query/es_query/from_kuery.ts index 8e6e64b4c984ed2..66b913e9439ad60 100644 --- a/packages/kbn-es-query/src/es_query/from_kuery.js +++ b/src/plugins/data/common/es_query/es_query/from_kuery.ts @@ -17,27 +17,40 @@ * under the License. */ -import { - fromKueryExpression, - toElasticsearchQuery, - nodeTypes, -} from '../kuery'; +import { fromKueryExpression, toElasticsearchQuery, nodeTypes, KueryNode } from '@kbn/es-query'; +import { IIndexPattern } from '../../index_patterns'; +import { Query } from '../../query/types'; -export function buildQueryFromKuery(indexPattern, queries = [], allowLeadingWildcards, dateFormatTZ = null) { +export function buildQueryFromKuery( + indexPattern: IIndexPattern | null, + queries: Query[] = [], + allowLeadingWildcards: boolean = false, + dateFormatTZ?: string +) { const queryASTs = queries.map(query => { return fromKueryExpression(query.query, { allowLeadingWildcards }); }); + return buildQuery(indexPattern, queryASTs, { dateFormatTZ }); } -function buildQuery(indexPattern, queryASTs, config = null) { - const compoundQueryAST = nodeTypes.function.buildNode('and', queryASTs); - const kueryQuery = toElasticsearchQuery(compoundQueryAST, indexPattern, config); +function buildQuery( + indexPattern: IIndexPattern | null, + queryASTs: any, + config: Record = {} +) { + const compoundQueryAST: KueryNode = nodeTypes.function.buildNode('and', queryASTs); + const kueryQuery: Record = toElasticsearchQuery( + compoundQueryAST, + indexPattern, + config + ); + return { must: [], filter: [], should: [], must_not: [], - ...kueryQuery.bool + ...kueryQuery.bool, }; } diff --git a/src/plugins/data/common/es_query/es_query/from_lucene.test.ts b/src/plugins/data/common/es_query/es_query/from_lucene.test.ts new file mode 100644 index 000000000000000..fc85404a5060cc4 --- /dev/null +++ b/src/plugins/data/common/es_query/es_query/from_lucene.test.ts @@ -0,0 +1,74 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { buildQueryFromLucene } from './from_lucene'; +import { decorateQuery } from './decorate_query'; +import { luceneStringToDsl } from './lucene_string_to_dsl'; +import { Query } from '../../query/types'; + +describe('build query', () => { + describe('buildQueryFromLucene', () => { + test('should return the parameters of an Elasticsearch bool query', () => { + const result = buildQueryFromLucene([], {}); + const expected = { + must: [], + filter: [], + should: [], + must_not: [], + }; + + expect(result).toEqual(expected); + }); + + test("should transform an array of lucene queries into ES queries combined in the bool's must clause", () => { + const queries = ([ + { query: 'foo:bar', language: 'lucene' }, + { query: 'bar:baz', language: 'lucene' }, + ] as unknown) as Query[]; + const expectedESQueries = queries.map(query => { + return decorateQuery(luceneStringToDsl(query.query), {}); + }); + + const result = buildQueryFromLucene(queries, {}); + + expect(result.must).toEqual(expectedESQueries); + }); + + test('should also accept queries in ES query DSL format, simply passing them through', () => { + const queries = ([{ query: { match_all: {} }, language: 'lucene' }] as unknown) as Query[]; + const result = buildQueryFromLucene(queries, {}); + + expect(result.must).toEqual([queries[0].query]); + }); + }); + + test("should accept a date format in the decorated queries and combine that into the bool's must clause", () => { + const queries = ([ + { query: 'foo:bar', language: 'lucene' }, + { query: 'bar:baz', language: 'lucene' }, + ] as unknown) as Query[]; + const dateFormatTZ = 'America/Phoenix'; + const expectedESQueries = queries.map(query => { + return decorateQuery(luceneStringToDsl(query.query), {}, dateFormatTZ); + }); + const result = buildQueryFromLucene(queries, {}, dateFormatTZ); + + expect(result.must).toEqual(expectedESQueries); + }); +}); diff --git a/packages/kbn-es-query/src/es_query/from_lucene.js b/src/plugins/data/common/es_query/es_query/from_lucene.ts similarity index 79% rename from packages/kbn-es-query/src/es_query/from_lucene.js rename to src/plugins/data/common/es_query/es_query/from_lucene.ts index 8845fd68efb4d63..b897341049a2b5d 100644 --- a/packages/kbn-es-query/src/es_query/from_lucene.js +++ b/src/plugins/data/common/es_query/es_query/from_lucene.ts @@ -16,19 +16,23 @@ * specific language governing permissions and limitations * under the License. */ - -import _ from 'lodash'; +import { map } from 'lodash'; import { decorateQuery } from './decorate_query'; import { luceneStringToDsl } from './lucene_string_to_dsl'; +import { Query } from '../../query/types'; -export function buildQueryFromLucene(queries, queryStringOptions, dateFormatTZ = null) { - const combinedQueries = _.map(queries, (query) => { +export function buildQueryFromLucene( + queries: Query[], + queryStringOptions: Record, + dateFormatTZ?: string +) { + const combinedQueries = map(queries, query => { const queryDsl = luceneStringToDsl(query.query); return decorateQuery(queryDsl, queryStringOptions, dateFormatTZ); }); return { - must: [].concat(combinedQueries), + must: combinedQueries, filter: [], should: [], must_not: [], diff --git a/packages/kbn-es-query/src/es_query/__tests__/get_es_query_config.js b/src/plugins/data/common/es_query/es_query/get_es_query_config.test.ts similarity index 69% rename from packages/kbn-es-query/src/es_query/__tests__/get_es_query_config.js rename to src/plugins/data/common/es_query/es_query/get_es_query_config.test.ts index 8ccb04dd4b25a2c..a4ab03687f92e98 100644 --- a/packages/kbn-es-query/src/es_query/__tests__/get_es_query_config.js +++ b/src/plugins/data/common/es_query/es_query/get_es_query_config.test.ts @@ -16,13 +16,13 @@ * specific language governing permissions and limitations * under the License. */ +import { get } from 'lodash'; +import { getEsQueryConfig } from './get_es_query_config'; +import { UiSettingsClientContract } from 'kibana/public'; -import expect from '@kbn/expect'; -import { getEsQueryConfig } from '../get_es_query_config'; - -const config = { - get(item) { - return config[item]; +const config = ({ + get(item: string) { + return get(config, item); }, 'query:allowLeadingWildcards': { allowLeadingWildcards: true, @@ -36,10 +36,10 @@ const config = { 'dateFormat:tz': { dateFormatTZ: 'Browser', }, -}; +} as unknown) as UiSettingsClientContract; -describe('getEsQueryConfig', function () { - it('should return the parameters of an Elasticsearch query config requested', function () { +describe('getEsQueryConfig', () => { + test('should return the parameters of an Elasticsearch query config requested', () => { const result = getEsQueryConfig(config); const expected = { allowLeadingWildcards: { @@ -55,12 +55,12 @@ describe('getEsQueryConfig', function () { queryStringOptions: {}, }, }; - expect(result).to.eql(expected); - expect(result).to.have.keys( - 'allowLeadingWildcards', - 'dateFormatTZ', - 'ignoreFilterIfFieldNotInIndex', - 'queryStringOptions' - ); + + expect(result).toEqual(expected); + + expect(result).toHaveProperty('allowLeadingWildcards'); + expect(result).toHaveProperty('dateFormatTZ'); + expect(result).toHaveProperty('ignoreFilterIfFieldNotInIndex'); + expect(result).toHaveProperty('queryStringOptions'); }); }); diff --git a/packages/kbn-es-query/src/es_query/get_es_query_config.js b/src/plugins/data/common/es_query/es_query/get_es_query_config.ts similarity index 78% rename from packages/kbn-es-query/src/es_query/get_es_query_config.js rename to src/plugins/data/common/es_query/es_query/get_es_query_config.ts index 2518b1077462d40..0a82cf03bdb4451 100644 --- a/packages/kbn-es-query/src/es_query/get_es_query_config.js +++ b/src/plugins/data/common/es_query/es_query/get_es_query_config.ts @@ -17,10 +17,22 @@ * under the License. */ -export function getEsQueryConfig(config) { +import { EsQueryConfig } from './build_es_query'; + +interface KibanaConfig { + get(key: string): T; +} + +export function getEsQueryConfig(config: KibanaConfig) { const allowLeadingWildcards = config.get('query:allowLeadingWildcards'); const queryStringOptions = config.get('query:queryString:options'); const ignoreFilterIfFieldNotInIndex = config.get('courier:ignoreFilterIfFieldNotInIndex'); const dateFormatTZ = config.get('dateFormat:tz'); - return { allowLeadingWildcards, queryStringOptions, ignoreFilterIfFieldNotInIndex, dateFormatTZ }; + + return { + allowLeadingWildcards, + queryStringOptions, + ignoreFilterIfFieldNotInIndex, + dateFormatTZ, + } as EsQueryConfig; } diff --git a/packages/kbn-es-query/src/es_query/index.js b/src/plugins/data/common/es_query/es_query/index.ts similarity index 94% rename from packages/kbn-es-query/src/es_query/index.js rename to src/plugins/data/common/es_query/es_query/index.ts index 57dc31fd9fb6fca..82cbc543e19dba4 100644 --- a/packages/kbn-es-query/src/es_query/index.js +++ b/src/plugins/data/common/es_query/es_query/index.ts @@ -17,7 +17,7 @@ * under the License. */ -export { buildEsQuery } from './build_es_query'; +export { buildEsQuery, EsQueryConfig } from './build_es_query'; export { buildQueryFromFilters } from './from_filters'; export { luceneStringToDsl } from './lucene_string_to_dsl'; export { migrateFilter } from './migrate_filter'; diff --git a/packages/kbn-es-query/src/es_query/__tests__/lucene_string_to_dsl.js b/src/plugins/data/common/es_query/es_query/lucene_string_to_dsl.test.ts similarity index 58% rename from packages/kbn-es-query/src/es_query/__tests__/lucene_string_to_dsl.js rename to src/plugins/data/common/es_query/es_query/lucene_string_to_dsl.test.ts index 04f6209ce6665bc..a0e94f2c46dcc45 100644 --- a/packages/kbn-es-query/src/es_query/__tests__/lucene_string_to_dsl.js +++ b/src/plugins/data/common/es_query/es_query/lucene_string_to_dsl.test.ts @@ -17,37 +17,34 @@ * under the License. */ -import { luceneStringToDsl } from '../lucene_string_to_dsl'; -import expect from '@kbn/expect'; +import { luceneStringToDsl } from './lucene_string_to_dsl'; -describe('build query', function () { - - describe('luceneStringToDsl', function () { - - it('should wrap strings with an ES query_string query', function () { +describe('build query', () => { + describe('luceneStringToDsl', () => { + test('should wrap strings with an ES query_string query', () => { const result = luceneStringToDsl('foo:bar'); const expectedResult = { - query_string: { query: 'foo:bar' } + query_string: { query: 'foo:bar' }, }; - expect(result).to.eql(expectedResult); + + expect(result).toEqual(expectedResult); }); - it('should return a match_all query for empty strings and whitespace', function () { + test('should return a match_all query for empty strings and whitespace', () => { const expectedResult = { - match_all: {} + match_all: {}, }; - expect(luceneStringToDsl('')).to.eql(expectedResult); - expect(luceneStringToDsl(' ')).to.eql(expectedResult); + expect(luceneStringToDsl('')).toEqual(expectedResult); + expect(luceneStringToDsl(' ')).toEqual(expectedResult); }); - it('should return non-string arguments without modification', function () { + test('should return non-string arguments without modification', () => { const expectedResult = {}; const result = luceneStringToDsl(expectedResult); - expect(result).to.be(expectedResult); - expect(result).to.eql(expectedResult); - }); + expect(result).toBe(expectedResult); + expect(result).toEqual(expectedResult); + }); }); - }); diff --git a/packages/kbn-es-query/src/es_query/filter_matches_index.js b/src/plugins/data/common/es_query/es_query/lucene_string_to_dsl.ts similarity index 66% rename from packages/kbn-es-query/src/es_query/filter_matches_index.js rename to src/plugins/data/common/es_query/es_query/lucene_string_to_dsl.ts index 602a9bbfbc9255e..6e8d519ec0ce28a 100644 --- a/packages/kbn-es-query/src/es_query/filter_matches_index.js +++ b/src/plugins/data/common/es_query/es_query/lucene_string_to_dsl.ts @@ -17,12 +17,17 @@ * under the License. */ -// TODO: We should base this on something better than `filter.meta.key`. We should probably modify -// this to check if `filter.meta.index` matches `indexPattern.id` instead, but that's a breaking -// change. -export function filterMatchesIndex(filter, indexPattern) { - if (!filter.meta || !indexPattern) { - return true; +import { isString } from 'lodash'; +import { DslQuery } from './es_query_dsl'; + +export function luceneStringToDsl(query: string | any): DslQuery { + if (isString(query)) { + if (query.trim() === '') { + return { match_all: {} }; + } + + return { query_string: { query } }; } - return indexPattern.fields.some(field => field.name === filter.meta.key); + + return query; } diff --git a/src/plugins/data/common/es_query/es_query/migrate_filter.test.ts b/src/plugins/data/common/es_query/es_query/migrate_filter.test.ts new file mode 100644 index 000000000000000..4617ee1a1c43d38 --- /dev/null +++ b/src/plugins/data/common/es_query/es_query/migrate_filter.test.ts @@ -0,0 +1,65 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { isEqual, clone } from 'lodash'; +import { migrateFilter, DeprecatedMatchPhraseFilter } from './migrate_filter'; +import { PhraseFilter, MatchAllFilter } from '../filters'; + +describe('migrateFilter', function() { + const oldMatchPhraseFilter = ({ + match: { + fieldFoo: { + query: 'foobar', + type: 'phrase', + }, + }, + } as unknown) as DeprecatedMatchPhraseFilter; + + const newMatchPhraseFilter = ({ + match_phrase: { + fieldFoo: { + query: 'foobar', + }, + }, + } as unknown) as PhraseFilter; + + it('should migrate match filters of type phrase', function() { + const migratedFilter = migrateFilter(oldMatchPhraseFilter, null); + + expect(isEqual(migratedFilter, newMatchPhraseFilter)).toBe(true); + }); + + it('should not modify the original filter', function() { + const oldMatchPhraseFilterCopy = clone(oldMatchPhraseFilter, true); + + migrateFilter(oldMatchPhraseFilter, null); + + expect(isEqual(oldMatchPhraseFilter, oldMatchPhraseFilterCopy)).toBe(true); + }); + + it('should return the original filter if no migration is necessary', function() { + const originalFilter = { + match_all: {}, + } as MatchAllFilter; + const migratedFilter = migrateFilter(originalFilter, null); + + expect(migratedFilter).toBe(originalFilter); + expect(isEqual(migratedFilter, originalFilter)).toBe(true); + }); +}); diff --git a/src/plugins/data/common/es_query/es_query/migrate_filter.ts b/src/plugins/data/common/es_query/es_query/migrate_filter.ts new file mode 100644 index 000000000000000..258ab9e7031319b --- /dev/null +++ b/src/plugins/data/common/es_query/es_query/migrate_filter.ts @@ -0,0 +1,65 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { get, omit } from 'lodash'; +import { getConvertedValueForField } from '../filters'; +import { Filter } from '../filters'; +import { IIndexPattern } from '../../index_patterns'; + +/** @deprecated + * see https://github.com/elastic/elasticsearch/pull/17508 + * */ +export interface DeprecatedMatchPhraseFilter extends Filter { + match: { + [field: string]: { + query: any; + type: 'phrase'; + }; + }; +} + +/** @deprecated + * see https://github.com/elastic/elasticsearch/pull/17508 + * */ +function isMatchPhraseFilter(filter: any): filter is DeprecatedMatchPhraseFilter { + const fieldName = filter.match && Object.keys(filter.match)[0]; + + return Boolean(fieldName && get(filter, ['match', fieldName, 'type']) === 'phrase'); +} + +export function migrateFilter(filter: Filter, indexPattern: IIndexPattern | null) { + if (isMatchPhraseFilter(filter)) { + const fieldName = Object.keys(filter.match)[0]; + const params: Record = get(filter, ['match', fieldName]); + if (indexPattern) { + const field = indexPattern.fields.find(f => f.name === fieldName); + + if (field) { + params.query = getConvertedValueForField(field, params.query); + } + } + return { + match_phrase: { + [fieldName]: omit(params, 'type'), + }, + }; + } + + return filter; +} diff --git a/src/plugins/data/common/es_query/filters/exists_filter.ts b/src/plugins/data/common/es_query/filters/exists_filter.ts index 9125048e5f6cd0a..15d3256ced33b74 100644 --- a/src/plugins/data/common/es_query/filters/exists_filter.ts +++ b/src/plugins/data/common/es_query/filters/exists_filter.ts @@ -18,7 +18,8 @@ */ import { Filter, FilterMeta } from './meta_filter'; -import { IndexPattern, Field } from './types'; +import { IIndexPattern } from '../../index_patterns'; +import { IFieldType } from '../../fields'; export type ExistsFilterMeta = FilterMeta; @@ -33,7 +34,7 @@ export type ExistsFilter = Filter & { export const isExistsFilter = (filter: any): filter is ExistsFilter => filter && filter.exists; -export const buildExistsFilter = (field: Field, indexPattern: IndexPattern) => { +export const buildExistsFilter = (field: IFieldType, indexPattern: IIndexPattern) => { return { meta: { index: indexPattern.id, diff --git a/src/plugins/data/common/es_query/filters/index.ts b/src/plugins/data/common/es_query/filters/index.ts index e28ce9ba74975cc..c19545eb83a0601 100644 --- a/src/plugins/data/common/es_query/filters/index.ts +++ b/src/plugins/data/common/es_query/filters/index.ts @@ -17,6 +17,9 @@ * under the License. */ +import { omit, get } from 'lodash'; +import { Filter } from './meta_filter'; + export * from './custom_filter'; export * from './exists_filter'; export * from './geo_bounding_box_filter'; @@ -30,3 +33,12 @@ export * from './query_string_filter'; export * from './range_filter'; export * from './types'; + +/** + * Clean out any invalid attributes from the filters + * @param {object} filter The filter to clean + * @returns {object} + */ +export const cleanFilter = (filter: Filter): Filter => omit(filter, ['meta', '$state']); + +export const isFilterDisabled = (filter: Filter): boolean => get(filter, 'meta.disabled', false); diff --git a/src/plugins/data/common/es_query/filters/phrase_filter.test.ts b/src/plugins/data/common/es_query/filters/phrase_filter.test.ts index ec13e28c583d185..3f093dccf46712d 100644 --- a/src/plugins/data/common/es_query/filters/phrase_filter.test.ts +++ b/src/plugins/data/common/es_query/filters/phrase_filter.test.ts @@ -18,16 +18,16 @@ */ import { buildInlineScriptForPhraseFilter, buildPhraseFilter } from './phrase_filter'; -import { IndexPattern } from './types'; import { getField } from '../__tests__/fields_mock'; +import { IIndexPattern } from '../../index_patterns'; describe('Phrase filter builder', () => { - let indexPattern: IndexPattern; + let indexPattern: IIndexPattern; beforeEach(() => { indexPattern = { id: 'id', - }; + } as IIndexPattern; }); it('should be a function', () => { diff --git a/src/plugins/data/common/es_query/filters/phrase_filter.ts b/src/plugins/data/common/es_query/filters/phrase_filter.ts index 15c5c9d4ad2e6df..c7673ed7de590f7 100644 --- a/src/plugins/data/common/es_query/filters/phrase_filter.ts +++ b/src/plugins/data/common/es_query/filters/phrase_filter.ts @@ -19,7 +19,8 @@ import { get, isPlainObject } from 'lodash'; import { Filter, FilterMeta } from './meta_filter'; -import { IndexPattern, Field } from './types'; +import { IIndexPattern } from '../../index_patterns'; +import { IFieldType } from '../../fields'; export type PhraseFilterMeta = FilterMeta & { params?: { @@ -51,7 +52,7 @@ export const isPhraseFilter = (filter: any): filter is PhraseFilter => { filter.query.match && Object.values(filter.query.match).find((params: any) => params.type === 'phrase'); - return !!(isMatchPhraseQuery || isDeprecatedMatchPhraseQuery); + return Boolean(isMatchPhraseQuery || isDeprecatedMatchPhraseQuery); }; export const isScriptedPhraseFilter = (filter: any): filter is PhraseFilter => @@ -69,9 +70,9 @@ export const getPhraseFilterValue = (filter: PhraseFilter): PhraseFilterValue => }; export const buildPhraseFilter = ( - field: Field, + field: IFieldType, value: any, - indexPattern: IndexPattern + indexPattern: IIndexPattern ): PhraseFilter => { const convertedValue = getConvertedValueForField(field, value); @@ -92,7 +93,7 @@ export const buildPhraseFilter = ( } }; -export const getPhraseScript = (field: Field, value: string) => { +export const getPhraseScript = (field: IFieldType, value: string) => { const convertedValue = getConvertedValueForField(field, value); const script = buildInlineScriptForPhraseFilter(field); @@ -110,7 +111,7 @@ export const getPhraseScript = (field: Field, value: string) => { // See https://github.com/elastic/elasticsearch/issues/20941 and https://github.com/elastic/kibana/issues/8677 // and https://github.com/elastic/elasticsearch/pull/22201 // for the reason behind this change. Aggs now return boolean buckets with a key of 1 or 0. -export const getConvertedValueForField = (field: Field, value: any) => { +export const getConvertedValueForField = (field: IFieldType, value: any) => { if (typeof value !== 'boolean' && field.type === 'boolean') { if ([1, 'true'].includes(value)) { return true; diff --git a/src/plugins/data/common/es_query/filters/phrases_filter.ts b/src/plugins/data/common/es_query/filters/phrases_filter.ts index e4606695c0f6a55..39904897da8c132 100644 --- a/src/plugins/data/common/es_query/filters/phrases_filter.ts +++ b/src/plugins/data/common/es_query/filters/phrases_filter.ts @@ -18,8 +18,10 @@ */ import { Filter, FilterMeta } from './meta_filter'; -import { Field, IndexPattern } from './types'; import { getPhraseScript } from './phrase_filter'; +import { FILTERS } from './index'; +import { IIndexPattern } from '../../index_patterns'; +import { IFieldType } from '../../fields'; export type PhrasesFilterMeta = FilterMeta & { params: string[]; // The unformatted values @@ -31,16 +33,16 @@ export type PhrasesFilter = Filter & { }; export const isPhrasesFilter = (filter: any): filter is PhrasesFilter => - filter && filter.meta.type === 'phrases'; + filter && filter.meta.type === FILTERS.PHRASES; // Creates a filter where the given field matches one or more of the given values // params should be an array of values -export const buildPhrasesFilter = (field: Field, params: any, indexPattern: IndexPattern) => { +export const buildPhrasesFilter = (field: IFieldType, params: any, indexPattern: IIndexPattern) => { const index = indexPattern.id; - const type = 'phrases'; + const type = FILTERS.PHRASES; const key = field.name; - const format = (f: Field, value: any) => + const format = (f: IFieldType, value: any) => f && f.format && f.format.convert ? f.format.convert(value) : value; const value = params.map((v: any) => format(field, v)).join(', '); diff --git a/src/plugins/data/common/es_query/filters/query_string_filter.test.ts b/src/plugins/data/common/es_query/filters/query_string_filter.test.ts index 839e4f6359257ec..4fcb15ccac44a4b 100644 --- a/src/plugins/data/common/es_query/filters/query_string_filter.test.ts +++ b/src/plugins/data/common/es_query/filters/query_string_filter.test.ts @@ -18,26 +18,17 @@ */ import { buildQueryFilter } from './query_string_filter'; -import { IndexPattern } from './types'; describe('Phrase filter builder', () => { - let indexPattern: IndexPattern; - - beforeEach(() => { - indexPattern = { - id: 'id', - }; - }); - it('should be a function', () => { expect(typeof buildQueryFilter).toBe('function'); }); it('should return a query filter when passed a standard field', () => { - expect(buildQueryFilter({ foo: 'bar' }, indexPattern.id, '')).toEqual({ + expect(buildQueryFilter({ foo: 'bar' }, 'index', '')).toEqual({ meta: { alias: '', - index: 'id', + index: 'index', }, query: { foo: 'bar', diff --git a/src/plugins/data/common/es_query/filters/query_string_filter.ts b/src/plugins/data/common/es_query/filters/query_string_filter.ts index 901dc724aa4e49a..a0e563eca6334df 100644 --- a/src/plugins/data/common/es_query/filters/query_string_filter.ts +++ b/src/plugins/data/common/es_query/filters/query_string_filter.ts @@ -18,7 +18,6 @@ */ import { Filter, FilterMeta } from './meta_filter'; -import { IndexPattern } from './types'; export type QueryStringFilterMeta = FilterMeta; @@ -35,11 +34,7 @@ export const isQueryStringFilter = (filter: any): filter is QueryStringFilter => filter && filter.query && filter.query.query_string; // Creates a filter corresponding to a raw Elasticsearch query DSL object -export const buildQueryFilter = ( - query: QueryStringFilter['query'], - index: IndexPattern, - alias: string -) => +export const buildQueryFilter = (query: QueryStringFilter['query'], index: string, alias: string) => ({ query, meta: { diff --git a/src/plugins/data/common/es_query/filters/range_filter.test.ts b/src/plugins/data/common/es_query/filters/range_filter.test.ts index 9008dc2a672944b..cf4b4b25664f7b8 100644 --- a/src/plugins/data/common/es_query/filters/range_filter.test.ts +++ b/src/plugins/data/common/es_query/filters/range_filter.test.ts @@ -19,16 +19,17 @@ import { each } from 'lodash'; import { buildRangeFilter, RangeFilter } from './range_filter'; -import { IndexPattern, Field } from './types'; import { getField } from '../__tests__/fields_mock'; +import { IIndexPattern } from '../../index_patterns'; +import { IFieldType } from '../../fields'; describe('Range filter builder', () => { - let indexPattern: IndexPattern; + let indexPattern: IIndexPattern; beforeEach(() => { indexPattern = { id: 'id', - }; + } as IIndexPattern; }); it('should be a function', () => { @@ -118,7 +119,7 @@ describe('Range filter builder', () => { }); describe('when given params where one side is infinite', () => { - let field: Field; + let field: IFieldType; let filter: RangeFilter; beforeEach(() => { @@ -148,7 +149,7 @@ describe('Range filter builder', () => { }); describe('when given params where both sides are infinite', () => { - let field: Field; + let field: IFieldType; let filter: RangeFilter; beforeEach(() => { diff --git a/src/plugins/data/common/es_query/filters/range_filter.ts b/src/plugins/data/common/es_query/filters/range_filter.ts index d7931f191e52b1b..9b93b8bbd948d06 100644 --- a/src/plugins/data/common/es_query/filters/range_filter.ts +++ b/src/plugins/data/common/es_query/filters/range_filter.ts @@ -18,7 +18,8 @@ */ import { map, reduce, mapValues, get, keys, pick } from 'lodash'; import { Filter, FilterMeta } from './meta_filter'; -import { Field, IndexPattern } from './types'; +import { IIndexPattern } from '../../index_patterns'; +import { IFieldType } from '../../fields'; const OPERANDS_IN_RANGE = 2; @@ -84,18 +85,18 @@ export const isScriptedRangeFilter = (filter: any): filter is RangeFilter => { return hasRangeKeys(params); }; -const formatValue = (field: Field, params: any[]) => +const formatValue = (field: IFieldType, params: any[]) => map(params, (val: any, key: string) => get(operators, key) + format(field, val)).join(' '); -const format = (field: Field, value: any) => +const format = (field: IFieldType, value: any) => field && field.format && field.format.convert ? field.format.convert(value) : value; // Creates a filter where the value for the given field is in the given range // params should be an object containing `lt`, `lte`, `gt`, and/or `gte` export const buildRangeFilter = ( - field: Field, + field: IFieldType, params: RangeFilterParams, - indexPattern: IndexPattern, + indexPattern: IIndexPattern, formattedValue?: string ): RangeFilter => { const filter: any = { meta: { index: indexPattern.id, params: {} } }; @@ -139,7 +140,7 @@ export const buildRangeFilter = ( return filter as RangeFilter; }; -export const getRangeScript = (field: IndexPattern, params: RangeFilterParams) => { +export const getRangeScript = (field: IFieldType, params: RangeFilterParams) => { const knownParams = pick(params, (val, key: any) => key in operators); let script = map( knownParams, diff --git a/src/plugins/data/common/es_query/filters/types.ts b/src/plugins/data/common/es_query/filters/types.ts index 281473506199956..a242df4811c0591 100644 --- a/src/plugins/data/common/es_query/filters/types.ts +++ b/src/plugins/data/common/es_query/filters/types.ts @@ -49,9 +49,3 @@ export enum FILTERS { GEO_BOUNDING_BOX = 'geo_bounding_box', GEO_POLYGON = 'geo_polygon', } - -// We can't import the real types from the data plugin, so need to either duplicate -// them here or figure out another solution, perhaps housing them in this package -// will be replaces after Fieds / IndexPattern will be moved into new platform -export type Field = any; -export type IndexPattern = any; diff --git a/src/plugins/data/common/es_query/index.ts b/src/plugins/data/common/es_query/index.ts index 88e14a43cfaae28..56eb45c4b1dcafe 100644 --- a/src/plugins/data/common/es_query/index.ts +++ b/src/plugins/data/common/es_query/index.ts @@ -16,6 +16,8 @@ * specific language governing permissions and limitations * under the License. */ +import * as esQuery from './es_query'; import * as esFilters from './filters'; +import * as utils from './utils'; -export { esFilters }; +export { esFilters, esQuery, utils }; diff --git a/packages/kbn-es-query/src/es_query/lucene_string_to_dsl.js b/src/plugins/data/common/es_query/utils/get_time_zone_from_settings.ts similarity index 78% rename from packages/kbn-es-query/src/es_query/lucene_string_to_dsl.js rename to src/plugins/data/common/es_query/utils/get_time_zone_from_settings.ts index 36ff621e8a69480..303bd3547f2ff5f 100644 --- a/packages/kbn-es-query/src/es_query/lucene_string_to_dsl.js +++ b/src/plugins/data/common/es_query/utils/get_time_zone_from_settings.ts @@ -17,16 +17,10 @@ * under the License. */ -import _ from 'lodash'; +import moment from 'moment-timezone'; -export function luceneStringToDsl(query) { - if (!_.isString(query)) { - return query; - } +export function getTimeZoneFromSettings(dateFormatTZ: string) { + const detectedTimezone = moment.tz.guess(); - if (query.trim() === '') { - return { match_all: {} }; - } - - return { query_string: { query } }; + return dateFormatTZ === 'Browser' ? detectedTimezone : dateFormatTZ; } diff --git a/src/plugins/data/common/es_query/utils/index.ts b/src/plugins/data/common/es_query/utils/index.ts new file mode 100644 index 000000000000000..27f51c1f44cf2f0 --- /dev/null +++ b/src/plugins/data/common/es_query/utils/index.ts @@ -0,0 +1,20 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export * from './get_time_zone_from_settings'; diff --git a/src/plugins/data/common/fields/index.ts b/src/plugins/data/common/fields/index.ts new file mode 100644 index 000000000000000..d8f7b5091eb8f6b --- /dev/null +++ b/src/plugins/data/common/fields/index.ts @@ -0,0 +1,20 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export * from './types'; diff --git a/src/plugins/data/common/fields/types.ts b/src/plugins/data/common/fields/types.ts new file mode 100644 index 000000000000000..c336472a1e7d6f6 --- /dev/null +++ b/src/plugins/data/common/fields/types.ts @@ -0,0 +1,44 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export interface IFieldSubType { + multi?: { parent: string }; + nested?: { path: string }; +} + +export interface IFieldType { + name: string; + type: string; + script?: string; + lang?: string; + count?: number; + // esTypes might be undefined on old index patterns that have not been refreshed since we added + // this prop. It is also undefined on scripted fields. + esTypes?: string[]; + aggregatable?: boolean; + filterable?: boolean; + searchable?: boolean; + sortable?: boolean; + visualizable?: boolean; + readFromDocValues?: boolean; + scripted?: boolean; + subType?: IFieldSubType; + displayName?: string; + format?: any; +} diff --git a/src/plugins/data/common/index_patterns/index.ts b/src/plugins/data/common/index_patterns/index.ts new file mode 100644 index 000000000000000..d8f7b5091eb8f6b --- /dev/null +++ b/src/plugins/data/common/index_patterns/index.ts @@ -0,0 +1,20 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export * from './types'; diff --git a/src/plugins/data/common/index_patterns/types.ts b/src/plugins/data/common/index_patterns/types.ts new file mode 100644 index 000000000000000..401c0fb1e47109d --- /dev/null +++ b/src/plugins/data/common/index_patterns/types.ts @@ -0,0 +1,35 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { IFieldType } from '../fields'; + +export interface IIndexPattern { + fields: IFieldType[]; + title: string; + id?: string; + type?: string; + timeFieldName?: string; + fieldFormatMap?: Record< + string, + { + id: string; + params: unknown; + } + >; +} diff --git a/src/plugins/data/common/types.ts b/src/plugins/data/common/types.ts index 9eda75d8abd0b6e..1703a1271fda9ce 100644 --- a/src/plugins/data/common/types.ts +++ b/src/plugins/data/common/types.ts @@ -21,3 +21,5 @@ export * from './field_formats/types'; export * from './timefilter/types'; export * from './query/types'; export * from './kbn_field_types/types'; +export * from './fields/types'; +export * from './index_patterns/types'; diff --git a/src/plugins/data/public/query/filter_manager/lib/dedup_filters.test.ts b/src/plugins/data/public/query/filter_manager/lib/dedup_filters.test.ts index 9b493add0886c64..ab74798a837fc00 100644 --- a/src/plugins/data/public/query/filter_manager/lib/dedup_filters.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/dedup_filters.test.ts @@ -19,12 +19,26 @@ import { dedupFilters } from './dedup_filters'; import { esFilters } from '../../../../common/es_query'; +import { IIndexPattern, IFieldType } from '../../../../common/types'; describe('filter manager utilities', () => { + let indexPattern: IIndexPattern; + + beforeEach(() => { + indexPattern = { + id: 'index', + } as IIndexPattern; + }); + describe('dedupFilters(existing, filters)', () => { test('should return only filters which are not in the existing', () => { const existing: esFilters.Filter[] = [ - esFilters.buildRangeFilter({ name: 'bytes' }, { from: 0, to: 1024 }, 'index', ''), + esFilters.buildRangeFilter( + { name: 'bytes' } as IFieldType, + { from: 0, to: 1024 }, + indexPattern, + '' + ), esFilters.buildQueryFilter( { match: { _term: { query: 'apache', type: 'phrase' } } }, 'index', @@ -32,7 +46,12 @@ describe('filter manager utilities', () => { ), ]; const filters: esFilters.Filter[] = [ - esFilters.buildRangeFilter({ name: 'bytes' }, { from: 1024, to: 2048 }, 'index', ''), + esFilters.buildRangeFilter( + { name: 'bytes' } as IFieldType, + { from: 1024, to: 2048 }, + indexPattern, + '' + ), esFilters.buildQueryFilter( { match: { _term: { query: 'apache', type: 'phrase' } } }, 'index', @@ -47,7 +66,12 @@ describe('filter manager utilities', () => { test('should ignore the disabled attribute when comparing ', () => { const existing: esFilters.Filter[] = [ - esFilters.buildRangeFilter({ name: 'bytes' }, { from: 0, to: 1024 }, 'index', ''), + esFilters.buildRangeFilter( + { name: 'bytes' } as IFieldType, + { from: 0, to: 1024 }, + indexPattern, + '' + ), { ...esFilters.buildQueryFilter( { match: { _term: { query: 'apache', type: 'phrase' } } }, @@ -58,7 +82,12 @@ describe('filter manager utilities', () => { }, ]; const filters: esFilters.Filter[] = [ - esFilters.buildRangeFilter({ name: 'bytes' }, { from: 1024, to: 2048 }, 'index', ''), + esFilters.buildRangeFilter( + { name: 'bytes' } as IFieldType, + { from: 1024, to: 2048 }, + indexPattern, + '' + ), esFilters.buildQueryFilter( { match: { _term: { query: 'apache', type: 'phrase' } } }, 'index1', @@ -73,7 +102,12 @@ describe('filter manager utilities', () => { test('should ignore $state attribute', () => { const existing: esFilters.Filter[] = [ - esFilters.buildRangeFilter({ name: 'bytes' }, { from: 0, to: 1024 }, 'index', ''), + esFilters.buildRangeFilter( + { name: 'bytes' } as IFieldType, + { from: 0, to: 1024 }, + indexPattern, + '' + ), { ...esFilters.buildQueryFilter( { match: { _term: { query: 'apache', type: 'phrase' } } }, @@ -84,7 +118,12 @@ describe('filter manager utilities', () => { }, ]; const filters: esFilters.Filter[] = [ - esFilters.buildRangeFilter({ name: 'bytes' }, { from: 1024, to: 2048 }, 'index', ''), + esFilters.buildRangeFilter( + { name: 'bytes' } as IFieldType, + { from: 1024, to: 2048 }, + indexPattern, + '' + ), { ...esFilters.buildQueryFilter( { match: { _term: { query: 'apache', type: 'phrase' } } }, diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_exists.test.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_exists.test.ts index ff0ed4f4e4d94a6..0d0d61fa336c882 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_exists.test.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_exists.test.ts @@ -20,11 +20,20 @@ import { mapExists } from './map_exists'; import { mapQueryString } from './map_query_string'; import { esFilters } from '../../../../../common/es_query'; +import { IIndexPattern, IFieldType } from '../../../../../common/types'; describe('filter manager utilities', () => { describe('mapExists()', () => { + let indexPattern: IIndexPattern; + + beforeEach(() => { + indexPattern = { + id: 'index', + } as IIndexPattern; + }); + test('should return the key and value for matching filters', async () => { - const filter = esFilters.buildExistsFilter({ name: '_type' }, 'index'); + const filter = esFilters.buildExistsFilter({ name: '_type' } as IFieldType, indexPattern); const result = mapExists(filter); expect(result).toHaveProperty('key', '_type'); diff --git a/src/plugins/data/public/query/timefilter/lib/extract_time_filter.test.ts b/src/plugins/data/public/query/timefilter/lib/extract_time_filter.test.ts index 981c50844c4f3ec..00a03ab1b474a19 100644 --- a/src/plugins/data/public/query/timefilter/lib/extract_time_filter.test.ts +++ b/src/plugins/data/public/query/timefilter/lib/extract_time_filter.test.ts @@ -19,8 +19,17 @@ import { extractTimeFilter } from './extract_time_filter'; import { esFilters } from '../../../../../../plugins/data/public'; +import { IIndexPattern, IFieldType } from '../../../../common/types'; describe('filter manager utilities', () => { + let indexPattern: IIndexPattern; + + beforeEach(() => { + indexPattern = { + id: 'logstash-*', + } as IIndexPattern; + }); + describe('extractTimeFilter()', () => { test('should detect timeFilter', async () => { const filters: esFilters.Filter[] = [ @@ -30,9 +39,9 @@ describe('filter manager utilities', () => { '' ), esFilters.buildRangeFilter( - { name: 'time' }, + { name: 'time' } as IFieldType, { gt: 1388559600000, lt: 1388646000000 }, - 'logstash-*' + indexPattern ), ]; const result = await extractTimeFilter('time', filters); @@ -48,7 +57,12 @@ describe('filter manager utilities', () => { 'logstash-*', '' ), - esFilters.buildRangeFilter({ name: '@timestamp' }, { from: 1, to: 2 }, 'logstash-*', ''), + esFilters.buildRangeFilter( + { name: '@timestamp' } as IFieldType, + { from: 1, to: 2 }, + indexPattern, + '' + ), ]; const result = await extractTimeFilter('time', filters); @@ -63,7 +77,7 @@ describe('filter manager utilities', () => { 'logstash-*', '' ), - esFilters.buildPhraseFilter({ name: 'time' }, 'banana', 'logstash-*'), + esFilters.buildPhraseFilter({ name: 'time' } as IFieldType, 'banana', indexPattern), ]; const result = await extractTimeFilter('time', filters); diff --git a/x-pack/legacy/plugins/canvas/server/lib/build_embeddable_filters.ts b/x-pack/legacy/plugins/canvas/server/lib/build_embeddable_filters.ts index ca34246531bff5e..f019f36af4e5643 100644 --- a/x-pack/legacy/plugins/canvas/server/lib/build_embeddable_filters.ts +++ b/x-pack/legacy/plugins/canvas/server/lib/build_embeddable_filters.ts @@ -4,11 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import { TimeRange } from 'src/plugins/data/public'; import { Filter } from '../../types'; // @ts-ignore Untyped Local import { buildBoolArray } from './build_bool_array'; -import { esFilters } from '../../../../../../src/plugins/data/common'; +import { TimeRange, esFilters } from '../../../../../../src/plugins/data/common'; export interface EmbeddableFilterInput { filters: esFilters.Filter[]; diff --git a/x-pack/legacy/plugins/lens/public/app_plugin/app.test.tsx b/x-pack/legacy/plugins/lens/public/app_plugin/app.test.tsx index 31d622c7089a86a..f3797434e540e88 100644 --- a/x-pack/legacy/plugins/lens/public/app_plugin/app.test.tsx +++ b/x-pack/legacy/plugins/lens/public/app_plugin/app.test.tsx @@ -12,8 +12,7 @@ import { EditorFrameInstance } from '../types'; import { Storage } from '../../../../../../src/plugins/kibana_utils/public'; import { Document, SavedObjectStore } from '../persistence'; import { mount } from 'enzyme'; -import { esFilters } from '../../../../../../src/plugins/data/public'; - +import { esFilters, IFieldType, IIndexPattern } from '../../../../../../src/plugins/data/public'; import { dataPluginMock } from '../../../../../../src/plugins/data/public/mocks'; const dataStartMock = dataPluginMock.createStartContract(); @@ -593,17 +592,17 @@ describe('Lens App', () => { args.editorFrame = frame; const instance = mount(); + const indexPattern = ({ id: 'index1' } as unknown) as IIndexPattern; + const field = ({ name: 'myfield' } as unknown) as IFieldType; - args.data.query.filterManager.setFilters([ - esFilters.buildExistsFilter({ name: 'myfield' }, { id: 'index1' }), - ]); + args.data.query.filterManager.setFilters([esFilters.buildExistsFilter(field, indexPattern)]); instance.update(); expect(frame.mount).toHaveBeenCalledWith( expect.any(Element), expect.objectContaining({ - filters: [esFilters.buildExistsFilter({ name: 'myfield' }, { id: 'index1' })], + filters: [esFilters.buildExistsFilter(field, indexPattern)], }) ); }); @@ -725,9 +724,10 @@ describe('Lens App', () => { query: { query: 'new', language: 'lucene' }, }); - args.data.query.filterManager.setFilters([ - esFilters.buildExistsFilter({ name: 'myfield' }, { id: 'index1' }), - ]); + const indexPattern = ({ id: 'index1' } as unknown) as IIndexPattern; + const field = ({ name: 'myfield' } as unknown) as IFieldType; + + args.data.query.filterManager.setFilters([esFilters.buildExistsFilter(field, indexPattern)]); instance.update(); instance.find(TopNavMenu).prop('onClearSavedQuery')!(); diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/data_panel_wrapper.tsx b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/data_panel_wrapper.tsx index a5509cdc9455958..8ecb6d0599bc770 100644 --- a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/data_panel_wrapper.tsx +++ b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/data_panel_wrapper.tsx @@ -7,13 +7,12 @@ import React, { useMemo, memo, useContext, useState } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiPopover, EuiButtonIcon, EuiContextMenuPanel, EuiContextMenuItem } from '@elastic/eui'; -import { Query } from 'src/plugins/data/common'; import { DatasourceDataPanelProps, Datasource } from '../../../public'; import { NativeRenderer } from '../../native_renderer'; import { Action } from './state_management'; import { DragContext } from '../../drag_drop'; import { StateSetter, FramePublicAPI } from '../../types'; -import { esFilters } from '../../../../../../../src/plugins/data/public'; +import { Query, esFilters } from '../../../../../../../src/plugins/data/public'; interface DataPanelWrapperProps { datasourceState: unknown; diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/save.test.ts b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/save.test.ts index f223a9c06a2a753..158a6cb8c979aa6 100644 --- a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/save.test.ts +++ b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/save.test.ts @@ -6,12 +6,15 @@ import { getSavedObjectFormat, Props } from './save'; import { createMockDatasource, createMockVisualization } from '../mocks'; -import { esFilters } from '../../../../../../../src/plugins/data/public'; +import { esFilters, IIndexPattern, IFieldType } from '../../../../../../../src/plugins/data/public'; describe('save editor frame state', () => { const mockVisualization = createMockVisualization(); mockVisualization.getPersistableState.mockImplementation(x => x); const mockDatasource = createMockDatasource(); + const mockIndexPattern = ({ id: 'indexpattern' } as unknown) as IIndexPattern; + const mockField = ({ name: '@timestamp' } as unknown) as IFieldType; + mockDatasource.getPersistableState.mockImplementation(x => x); const saveArgs: Props = { activeDatasources: { @@ -37,7 +40,7 @@ describe('save editor frame state', () => { }, query: { query: '', language: 'lucene' }, dateRange: { fromDate: 'now-7d', toDate: 'now' }, - filters: [esFilters.buildExistsFilter({ name: '@timestamp' }, { id: 'indexpattern' })], + filters: [esFilters.buildExistsFilter(mockField, mockIndexPattern)], }, }; diff --git a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/workspace_panel.test.tsx b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/workspace_panel.test.tsx index fd35ecd702d23a4..d1d0f7e8e8f636f 100644 --- a/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/workspace_panel.test.tsx +++ b/x-pack/legacy/plugins/lens/public/editor_frame_plugin/editor_frame/workspace_panel.test.tsx @@ -20,7 +20,7 @@ import { ReactWrapper } from 'enzyme'; import { DragDrop, ChildDragDropProvider } from '../../drag_drop'; import { Ast } from '@kbn/interpreter/common'; import { coreMock } from 'src/core/public/mocks'; -import { esFilters } from '../../../../../../../src/plugins/data/public'; +import { esFilters, IFieldType, IIndexPattern } from '../../../../../../../src/plugins/data/public'; const waitForPromises = () => new Promise(resolve => setTimeout(resolve)); @@ -378,10 +378,13 @@ describe('workspace_panel', () => { expect(expressionRendererMock).toHaveBeenCalledTimes(1); + const indexPattern = ({ id: 'index1' } as unknown) as IIndexPattern; + const field = ({ name: 'myfield' } as unknown) as IFieldType; + instance.setProps({ framePublicAPI: { ...framePublicAPI, - filters: [esFilters.buildExistsFilter({ name: 'myfield' }, { id: 'index1' })], + filters: [esFilters.buildExistsFilter(field, indexPattern)], }, }); diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/field_item.tsx b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/field_item.tsx index 962eece4977e014..3536ad80538916e 100644 --- a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/field_item.tsx +++ b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/field_item.tsx @@ -35,9 +35,12 @@ import { niceTimeFormatter, } from '@elastic/charts'; import { i18n } from '@kbn/i18n'; -import { buildEsQuery, getEsQueryConfig } from '@kbn/es-query'; -import { Query } from 'src/plugins/data/common'; -import { esFilters } from '../../../../../../src/plugins/data/public'; +import { + Query, + esFilters, + esQuery, + IIndexPattern, +} from '../../../../../../src/plugins/data/public'; // @ts-ignore import { fieldFormats } from '../../../../../../src/legacy/ui/public/registry/field_formats'; import { DraggedField } from './indexpattern'; @@ -128,7 +131,12 @@ export function FieldItem(props: FieldItemProps) { core.http .post(`/api/lens/index_stats/${indexPattern.title}/field`, { body: JSON.stringify({ - dslQuery: buildEsQuery(indexPattern, query, filters, getEsQueryConfig(core.uiSettings)), + dslQuery: esQuery.buildEsQuery( + indexPattern as IIndexPattern, + query, + filters, + esQuery.getEsQueryConfig(core.uiSettings) + ), fromDate: dateRange.fromDate, toDate: dateRange.toDate, timeFieldName: indexPattern.timeFieldName, diff --git a/x-pack/legacy/plugins/lens/public/persistence/saved_object_store.ts b/x-pack/legacy/plugins/lens/public/persistence/saved_object_store.ts index 460cd76e8390d5a..4337482663a9c8c 100644 --- a/x-pack/legacy/plugins/lens/public/persistence/saved_object_store.ts +++ b/x-pack/legacy/plugins/lens/public/persistence/saved_object_store.ts @@ -6,8 +6,7 @@ // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { SavedObjectAttributes } from 'src/core/server'; -import { Query } from 'src/plugins/data/common'; -import { esFilters } from '../../../../../../src/plugins/data/public'; +import { Query, esFilters } from '../../../../../../src/plugins/data/public'; export interface Document { id?: string; diff --git a/x-pack/legacy/plugins/lens/public/types.ts b/x-pack/legacy/plugins/lens/public/types.ts index b66bb7bee8f8ad8..896284e8097d8ef 100644 --- a/x-pack/legacy/plugins/lens/public/types.ts +++ b/x-pack/legacy/plugins/lens/public/types.ts @@ -7,13 +7,12 @@ import { Ast } from '@kbn/interpreter/common'; import { IconType } from '@elastic/eui/src/components/icon/icon'; import { CoreSetup } from 'src/core/public'; -import { Query } from 'src/plugins/data/common'; import { SavedQuery } from 'src/legacy/core_plugins/data/public'; import { KibanaDatatable } from '../../../../../src/legacy/core_plugins/interpreter/common'; import { DragContextState } from './drag_drop'; import { Document } from './persistence'; import { DateRange } from '../common'; -import { esFilters } from '../../../../../src/plugins/data/public'; +import { Query, esFilters } from '../../../../../src/plugins/data/public'; // eslint-disable-next-line export interface EditorFrameOptions {} diff --git a/x-pack/legacy/plugins/ml/public/datavisualizer/index_based/page.tsx b/x-pack/legacy/plugins/ml/public/datavisualizer/index_based/page.tsx index 9123858eef4e548..75f06b5f9b52d26 100644 --- a/x-pack/legacy/plugins/ml/public/datavisualizer/index_based/page.tsx +++ b/x-pack/legacy/plugins/ml/public/datavisualizer/index_based/page.tsx @@ -6,9 +6,6 @@ import React, { FC, Fragment, useEffect, useState } from 'react'; import { merge } from 'rxjs'; - -// @ts-ignore -import { decorateQuery, luceneStringToDsl } from '@kbn/es-query'; import { i18n } from '@kbn/i18n'; import { FieldType } from 'ui/index_patterns'; @@ -25,7 +22,7 @@ import { EuiSpacer, EuiTitle, } from '@elastic/eui'; - +import { esQuery } from '../../../../../../../src/plugins/data/public'; import { NavigationMenu } from '../../components/navigation_menu'; import { KBN_FIELD_TYPES } from '../../../../../../../src/plugins/data/public'; import { ML_JOB_FIELD_TYPES } from '../../../common/constants/field_types'; @@ -194,8 +191,8 @@ export const Page: FC = () => { }, }; } else { - qry = luceneStringToDsl(qryString); - decorateQuery(qry, kibanaConfig.get('query:queryString:options')); + qry = esQuery.luceneStringToDsl(qryString); + esQuery.decorateQuery(qry, kibanaConfig.get('query:queryString:options')); } setSearchQuery(qry); diff --git a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/utils/new_job_utils.ts b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/utils/new_job_utils.ts index 0a37cff050eb0cf..85beb32fffa3c31 100644 --- a/x-pack/legacy/plugins/ml/public/jobs/new_job_new/utils/new_job_utils.ts +++ b/x-pack/legacy/plugins/ml/public/jobs/new_job_new/utils/new_job_utils.ts @@ -5,13 +5,12 @@ */ import { SavedSearch } from 'src/legacy/core_plugins/kibana/public/discover/types'; -import { IndexPattern } from 'ui/index_patterns'; -import { buildEsQuery, getEsQueryConfig } from '@kbn/es-query'; import { KibanaConfigTypeFix } from '../../../contexts/kibana'; import { InjectorService } from '../../../../common/types/angular'; +import { esQuery, IIndexPattern } from '../../../../../../../../src/plugins/data/public'; export interface SearchItems { - indexPattern: IndexPattern; + indexPattern: IIndexPattern; savedSearch: SavedSearch; query: any; combinedQuery: any; @@ -55,8 +54,8 @@ export function SearchItemsProvider($injector: InjectorService) { const filters = fs.length ? fs : []; - const esQueryConfigs = getEsQueryConfig(kibanaConfig); - combinedQuery = buildEsQuery(indexPattern, [query], filters, esQueryConfigs); + const esQueryConfigs = esQuery.getEsQueryConfig(kibanaConfig); + combinedQuery = esQuery.buildEsQuery(indexPattern, [query], filters, esQueryConfigs); } return { diff --git a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/generate_csv_search.ts b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/generate_csv_search.ts index 2e2c8635fca5f0a..5454d0aa1cd0802 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/generate_csv_search.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/server/lib/generate_csv_search.ts @@ -4,30 +4,26 @@ * you may not use this file except in compliance with the Elastic License. */ -import { buildEsQuery } from '@kbn/es-query'; // @ts-ignore no module definition import { createGenerateCsv } from '../../../csv/server/lib/generate_csv'; import { CancellationToken } from '../../../../common/cancellation_token'; import { ServerFacade, RequestFacade, Logger } from '../../../../types'; -import { - IndexPatternSavedObject, - SavedSearchObjectAttributes, - SearchPanel, - SearchRequest, - SearchSource, - SearchSourceQuery, -} from '../../types'; +import { SavedSearchObjectAttributes, SearchPanel, SearchRequest, SearchSource } from '../../types'; import { CsvResultFromSearch, - ESQueryConfig, GenerateCsvParams, - Filter, IndexPatternField, QueryFilter, } from '../../types'; import { getDataSource } from './get_data_source'; import { getFilters } from './get_filters'; import { JobParamsDiscoverCsv } from '../../../csv/types'; +import { + esQuery, + esFilters, + IIndexPattern, + Query, +} from '../../../../../../../../src/plugins/data/common'; const getEsQueryConfig = async (config: any) => { const configs = await Promise.all([ @@ -36,7 +32,11 @@ const getEsQueryConfig = async (config: any) => { config.get('courier:ignoreFilterIfFieldNotInIndex'), ]); const [allowLeadingWildcards, queryStringOptions, ignoreFilterIfFieldNotInIndex] = configs; - return { allowLeadingWildcards, queryStringOptions, ignoreFilterIfFieldNotInIndex }; + return { + allowLeadingWildcards, + queryStringOptions, + ignoreFilterIfFieldNotInIndex, + } as esQuery.EsQueryConfig; }; const getUiSettings = async (config: any) => { @@ -116,21 +116,17 @@ export async function generateCsvSearch( }; }, {}); const docValueFields = indexPatternTimeField ? [indexPatternTimeField] : undefined; - - // this array helps ensure the params are passed to buildEsQuery (non-Typescript) in the right order - const buildCsvParams: [IndexPatternSavedObject, SearchSourceQuery, Filter[], ESQueryConfig] = [ - indexPatternSavedObject, - searchSourceQuery, - combinedFilter, - esQueryConfig, - ]; - const searchRequest: SearchRequest = { index: esIndex, body: { _source: { includes }, docvalue_fields: docValueFields, - query: buildEsQuery(...buildCsvParams), + query: esQuery.buildEsQuery( + indexPatternSavedObject as IIndexPattern, + (searchSourceQuery as unknown) as Query, + (combinedFilter as unknown) as esFilters.Filter, + esQueryConfig + ), script_fields: scriptFieldsConfig, sort: sortConfig, }, diff --git a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/types.d.ts b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/types.d.ts index f8692c336b29211..72caf551d2a3db9 100644 --- a/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/types.d.ts +++ b/x-pack/legacy/plugins/reporting/export_types/csv_from_savedobject/types.d.ts @@ -234,12 +234,6 @@ export interface SearchSourceFilter extends Filter { isSearchSourceFilter: boolean; } -export interface ESQueryConfig { - allowLeadingWildcards: boolean; - queryStringOptions: boolean; - ignoreFilterIfFieldNotInIndex: boolean; -} - export interface IndexPatternField { scripted: boolean; lang?: string; diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map.tsx b/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map.tsx index b9c28105e99d151..794e26b41701216 100644 --- a/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map.tsx +++ b/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map.tsx @@ -7,7 +7,6 @@ import { EuiLink, EuiText } from '@elastic/eui'; import React, { useEffect, useState } from 'react'; import { createPortalNode, InPortal } from 'react-reverse-portal'; -import { Query } from 'src/plugins/data/common'; import styled, { css } from 'styled-components'; import { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } from 'ui/documentation_links'; import { SavedObjectFinder } from 'ui/saved_objects/components/saved_object_finder'; @@ -29,7 +28,7 @@ import { IndexPatternsMissingPrompt } from './index_patterns_missing_prompt'; import { MapToolTip } from './map_tool_tip/map_tool_tip'; import * as i18n from './translations'; import { MapEmbeddable, SetQuery } from './types'; -import { esFilters } from '../../../../../../../src/plugins/data/public'; +import { Query, esFilters } from '../../../../../../../src/plugins/data/public'; interface EmbeddableMapProps { maintainRatio?: boolean; diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map_helpers.tsx b/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map_helpers.tsx index a50cfa98fc977a4..03c4492b77f1be4 100644 --- a/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map_helpers.tsx +++ b/x-pack/legacy/plugins/siem/public/components/embeddables/embedded_map_helpers.tsx @@ -7,7 +7,6 @@ import uuid from 'uuid'; import React from 'react'; import { OutPortal, PortalNode } from 'react-reverse-portal'; -import { Query } from 'src/plugins/data/common'; import { PluginsStart } from 'ui/new_platform/new_platform'; import { ActionToaster, AppToast } from '../toasters'; @@ -27,7 +26,7 @@ import { getLayerList } from './map_config'; // @ts-ignore Missing type defs as maps moves to Typescript import { MAP_SAVED_OBJECT_TYPE } from '../../../../maps/common/constants'; import * as i18n from './translations'; -import { esFilters } from '../../../../../../../src/plugins/data/public'; +import { Query, esFilters } from '../../../../../../../src/plugins/data/public'; /** * Displays an error toast for the provided title and message diff --git a/x-pack/legacy/plugins/siem/public/components/embeddables/types.ts b/x-pack/legacy/plugins/siem/public/components/embeddables/types.ts index 10412ecdb501312..fdda9f949280a83 100644 --- a/x-pack/legacy/plugins/siem/public/components/embeddables/types.ts +++ b/x-pack/legacy/plugins/siem/public/components/embeddables/types.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Query } from 'src/plugins/data/common'; import { TimeRange } from 'src/plugins/data/public'; import { EmbeddableInput, @@ -13,7 +12,7 @@ import { EmbeddableFactory, } from '../../../../../../../src/legacy/core_plugins/embeddable_api/public/np_ready/public'; import { inputsModel } from '../../store/inputs'; -import { esFilters } from '../../../../../../../src/plugins/data/public'; +import { Query, esFilters } from '../../../../../../../src/plugins/data/public'; export interface MapEmbeddableInput extends EmbeddableInput { filters: esFilters.Filter[]; diff --git a/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.tsx b/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.tsx index 6b79a6402586e86..2b588283bd198ca 100644 --- a/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.tsx +++ b/x-pack/legacy/plugins/siem/public/components/events_viewer/events_viewer.tsx @@ -5,12 +5,10 @@ */ import { EuiPanel } from '@elastic/eui'; -import { getEsQueryConfig } from '@kbn/es-query'; import { getOr, isEmpty, isEqual } from 'lodash/fp'; import React from 'react'; import styled from 'styled-components'; import { StaticIndexPattern } from 'ui/index_patterns'; -import { Query } from 'src/plugins/data/common'; import { BrowserFields } from '../../containers/source'; import { TimelineQuery } from '../../containers/timeline'; @@ -31,7 +29,7 @@ import { TimelineRefetch } from '../timeline/refetch_timeline'; import { isCompactFooter } from '../timeline/timeline'; import { ManageTimelineContext } from '../timeline/timeline_context'; import * as i18n from './translations'; -import { esFilters } from '../../../../../../../src/plugins/data/public'; +import { Query, esFilters, esQuery } from '../../../../../../../src/plugins/data/public'; const DEFAULT_EVENTS_VIEWER_HEIGHT = 500; @@ -85,7 +83,7 @@ export const EventsViewer = React.memo( const columnsHeader = isEmpty(columns) ? defaultHeaders : columns; const core = useKibanaCore(); const combinedQueries = combineQueries({ - config: getEsQueryConfig(core.uiSettings), + config: esQuery.getEsQueryConfig(core.uiSettings), dataProviders, indexPattern, browserFields, diff --git a/x-pack/legacy/plugins/siem/public/components/events_viewer/index.tsx b/x-pack/legacy/plugins/siem/public/components/events_viewer/index.tsx index 5681588cb44b711..642153e9cd213dc 100644 --- a/x-pack/legacy/plugins/siem/public/components/events_viewer/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/events_viewer/index.tsx @@ -8,8 +8,6 @@ import { isEqual } from 'lodash/fp'; import React, { useEffect, useState, useCallback } from 'react'; import { connect } from 'react-redux'; import { ActionCreator } from 'typescript-fsa'; -import { Query } from 'src/plugins/data/common'; - import { WithSource } from '../../containers/source'; import { inputsModel, inputsSelectors, State, timelineSelectors } from '../../store'; import { timelineActions, inputsActions } from '../../store/actions'; @@ -18,7 +16,7 @@ import { ColumnHeader } from '../timeline/body/column_headers/column_header'; import { DataProvider } from '../timeline/data_providers/data_provider'; import { Sort } from '../timeline/body/sort'; import { OnChangeItemsPerPage } from '../timeline/events'; -import { esFilters } from '../../../../../../../src/plugins/data/public'; +import { Query, esFilters } from '../../../../../../../src/plugins/data/public'; import { EventsViewer } from './events_viewer'; import { InputsModelId } from '../../store/inputs/constants'; diff --git a/x-pack/legacy/plugins/siem/public/components/navigation/helpers.ts b/x-pack/legacy/plugins/siem/public/components/navigation/helpers.ts index 0c44b8d44c31778..6d1017f93b54e7c 100644 --- a/x-pack/legacy/plugins/siem/public/components/navigation/helpers.ts +++ b/x-pack/legacy/plugins/siem/public/components/navigation/helpers.ts @@ -6,7 +6,6 @@ import { isEmpty } from 'lodash/fp'; import { Location } from 'history'; -import { Query } from 'src/plugins/data/common'; import { UrlInputsModel } from '../../store/inputs/model'; import { CONSTANTS } from '../url_state/constants'; @@ -16,7 +15,7 @@ import { replaceStateKeyInQueryString, getQueryStringFromLocation, } from '../url_state/helpers'; -import { esFilters } from '../../../../../../../src/plugins/data/public'; +import { Query, esFilters } from '../../../../../../../src/plugins/data/public'; import { TabNavigationProps } from './tab_navigation/types'; import { SearchNavTab } from './types'; diff --git a/x-pack/legacy/plugins/siem/public/components/search_bar/index.tsx b/x-pack/legacy/plugins/siem/public/components/search_bar/index.tsx index 5b60b625212936f..27a4127c2ed1d07 100644 --- a/x-pack/legacy/plugins/siem/public/components/search_bar/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/search_bar/index.tsx @@ -11,8 +11,6 @@ import { Dispatch } from 'redux'; import { Subscription } from 'rxjs'; import styled from 'styled-components'; import { StaticIndexPattern, IndexPattern } from 'ui/index_patterns'; - -import { TimeRange, Query } from 'src/plugins/data/common/types'; import { SavedQuery } from 'src/legacy/core_plugins/data/public'; import { OnTimeChangeProps } from '@elastic/eui'; @@ -36,7 +34,7 @@ import { toStrSelector, } from './selectors'; import { timelineActions, hostsActions, networkActions } from '../../store/actions'; -import { esFilters } from '../../../../../../../src/plugins/data/public'; +import { TimeRange, Query, esFilters } from '../../../../../../../src/plugins/data/public'; const { ui: { SearchBar }, diff --git a/x-pack/legacy/plugins/siem/public/components/search_bar/selectors.ts b/x-pack/legacy/plugins/siem/public/components/search_bar/selectors.ts index cfd7cd840dac8e1..34063d29f346f29 100644 --- a/x-pack/legacy/plugins/siem/public/components/search_bar/selectors.ts +++ b/x-pack/legacy/plugins/siem/public/components/search_bar/selectors.ts @@ -5,9 +5,9 @@ */ import { createSelector } from 'reselect'; -import { Query } from 'src/plugins/data/common'; import { SavedQuery } from 'src/legacy/core_plugins/data/public'; import { InputsRange } from '../../store/inputs/model'; +import { Query } from '../../../../../../../src/plugins/data/public'; export { endSelector, diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/helpers.test.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/helpers.test.tsx index b30771760bad377..2ed28869043a08b 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/helpers.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/helpers.test.tsx @@ -11,7 +11,7 @@ import { mockIndexPattern } from '../../mock'; import { mockDataProviders } from './data_providers/mock/mock_data_providers'; import { buildGlobalQuery, combineQueries } from './helpers'; import { mockBrowserFields } from '../../containers/source/mock'; -import { EsQueryConfig } from '../../lib/keury'; +import { esQuery } from '../../../../../../../src/plugins/data/public'; const cleanUpKqlQuery = (str: string) => str.replace(/\n/g, '').replace(/\s\s+/g, ' '); const startDate = new Date('2018-03-23T18:49:23.132Z').valueOf(); @@ -117,7 +117,7 @@ describe('Build KQL Query', () => { }); describe('Combined Queries', () => { - const config: EsQueryConfig = { + const config: esQuery.EsQueryConfig = { allowLeadingWildcards: true, queryStringOptions: {}, ignoreFilterIfFieldNotInIndex: true, diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/helpers.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/helpers.tsx index 6182fca6e2e9937..f2700ccd4f1a66b 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/helpers.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/helpers.tsx @@ -7,12 +7,12 @@ import { isEmpty, isNumber, get } from 'lodash/fp'; import memoizeOne from 'memoize-one'; import { StaticIndexPattern } from 'ui/index_patterns'; -import { Query, esFilters } from 'src/plugins/data/public'; -import { escapeQueryValue, convertToBuildEsQuery, EsQueryConfig } from '../../lib/keury'; +import { escapeQueryValue, convertToBuildEsQuery } from '../../lib/keury'; import { DataProvider, DataProvidersAnd, EXISTS_OPERATOR } from './data_providers/data_provider'; import { BrowserFields } from '../../containers/source'; +import { Query, esQuery, esFilters } from '../../../../../../../src/plugins/data/common'; const convertDateFieldToQuery = (field: string, value: string | number) => `${field}: ${isNumber(value) ? value : new Date(value).valueOf()}`; @@ -101,7 +101,7 @@ export const combineQueries = ({ end, isEventViewer, }: { - config: EsQueryConfig; + config: esQuery.EsQueryConfig; dataProviders: DataProvider[]; indexPattern: StaticIndexPattern; browserFields: BrowserFields; diff --git a/x-pack/legacy/plugins/siem/public/components/timeline/timeline.tsx b/x-pack/legacy/plugins/siem/public/components/timeline/timeline.tsx index fb62b636398c234..48ef8b191474528 100644 --- a/x-pack/legacy/plugins/siem/public/components/timeline/timeline.tsx +++ b/x-pack/legacy/plugins/siem/public/components/timeline/timeline.tsx @@ -5,7 +5,6 @@ */ import { EuiFlexGroup } from '@elastic/eui'; -import { getEsQueryConfig } from '@kbn/es-query'; import { getOr, isEmpty } from 'lodash/fp'; import * as React from 'react'; import styled from 'styled-components'; @@ -37,6 +36,7 @@ import { TimelineHeader } from './header'; import { calculateBodyHeight, combineQueries } from './helpers'; import { TimelineRefetch } from './refetch_timeline'; import { ManageTimelineContext } from './timeline_context'; +import { esQuery } from '../../../../../../../src/plugins/data/public'; const WrappedByAutoSizer = styled.div` width: 100%; @@ -115,7 +115,7 @@ export const Timeline = React.memo( }) => { const core = useKibanaCore(); const combinedQueries = combineQueries({ - config: getEsQueryConfig(core.uiSettings), + config: esQuery.getEsQueryConfig(core.uiSettings), dataProviders, indexPattern, browserFields, diff --git a/x-pack/legacy/plugins/siem/public/components/url_state/test_dependencies.ts b/x-pack/legacy/plugins/siem/public/components/url_state/test_dependencies.ts index f548fe9ee8d4868..5610e99faa1e629 100644 --- a/x-pack/legacy/plugins/siem/public/components/url_state/test_dependencies.ts +++ b/x-pack/legacy/plugins/siem/public/components/url_state/test_dependencies.ts @@ -5,8 +5,6 @@ */ import { ActionCreator } from 'typescript-fsa'; -import { Query } from 'src/plugins/data/common'; - import { DispatchUpdateTimeline } from '../open_timeline/types'; import { navTabs } from '../../pages/home/home_navigations'; import { SiemPageName } from '../../pages/home/types'; @@ -17,6 +15,7 @@ import { HostsTableType } from '../../store/hosts/model'; import { CONSTANTS } from './constants'; import { dispatchSetInitialStateFromUrl } from './initialize_redux_by_url'; import { UrlStateContainerPropTypes, LocationTypes } from './types'; +import { Query } from '../../../../../../../src/plugins/data/public'; type Action = 'PUSH' | 'POP' | 'REPLACE'; const pop: Action = 'POP'; diff --git a/x-pack/legacy/plugins/siem/public/lib/keury/index.ts b/x-pack/legacy/plugins/siem/public/lib/keury/index.ts index bf8726d5ed377f1..1c522a01e104e29 100644 --- a/x-pack/legacy/plugins/siem/public/lib/keury/index.ts +++ b/x-pack/legacy/plugins/siem/public/lib/keury/index.ts @@ -4,17 +4,20 @@ * you may not use this file except in compliance with the Elastic License. */ -import { buildEsQuery, fromKueryExpression, toElasticsearchQuery } from '@kbn/es-query'; +import { fromKueryExpression, toElasticsearchQuery } from '@kbn/es-query'; import { isEmpty, isString, flow } from 'lodash/fp'; -import { StaticIndexPattern } from 'ui/index_patterns'; -import { Query } from 'src/plugins/data/common'; -import { esFilters } from '../../../../../../../src/plugins/data/public'; +import { + Query, + esFilters, + esQuery, + IIndexPattern, +} from '../../../../../../../src/plugins/data/public'; import { KueryFilterQuery } from '../../store'; export const convertKueryToElasticSearchQuery = ( kueryExpression: string, - indexPattern: StaticIndexPattern + indexPattern: IIndexPattern ) => { try { return kueryExpression @@ -68,29 +71,21 @@ export const escapeKuery = flow( escapeWhitespace ); -export interface EsQueryConfig { - allowLeadingWildcards: boolean; - queryStringOptions: unknown; - ignoreFilterIfFieldNotInIndex: boolean; - dateFormatTZ?: string | null; -} - export const convertToBuildEsQuery = ({ config, indexPattern, queries, filters, }: { - config: EsQueryConfig; - indexPattern: StaticIndexPattern; + config: esQuery.EsQueryConfig; + indexPattern: IIndexPattern; queries: Query[]; filters: esFilters.Filter[]; }) => { try { return JSON.stringify( - buildEsQuery(indexPattern, queries, filters.filter(f => f.meta.disabled === false), { + esQuery.buildEsQuery(indexPattern, queries, filters.filter(f => f.meta.disabled === false), { ...config, - dateFormatTZ: null, }) ); } catch (exp) { diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx index d3a242b41da7b59..c7fdb32b6cf368f 100644 --- a/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/hosts/details/index.tsx @@ -5,7 +5,6 @@ */ import { EuiHorizontalRule, EuiSpacer } from '@elastic/eui'; -import { getEsQueryConfig } from '@kbn/es-query'; import React, { useContext, useEffect } from 'react'; import { compose } from 'redux'; import { connect } from 'react-redux'; @@ -34,6 +33,7 @@ import { convertToBuildEsQuery } from '../../../lib/keury'; import { setAbsoluteRangeDatePicker as dispatchAbsoluteRangeDatePicker } from '../../../store/inputs/actions'; import { SpyRoute } from '../../../utils/route/spy_routes'; import { useKibanaCore } from '../../../lib/compose/kibana_core'; +import { esQuery } from '../../../../../../../../src/plugins/data/public'; import { HostsEmptyPage } from '../hosts_empty_page'; import { navTabsHostDetails } from './nav_tabs'; @@ -68,7 +68,7 @@ const HostDetailsComponent = React.memo( {({ indicesExist, indexPattern }) => { const filterQuery = convertToBuildEsQuery({ - config: getEsQueryConfig(core.uiSettings), + config: esQuery.getEsQueryConfig(core.uiSettings), indexPattern, queries: [query], filters: [ diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx index 334d730378b236b..d914529d88340ce 100644 --- a/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/hosts/hosts.tsx @@ -5,7 +5,6 @@ */ import { EuiSpacer } from '@elastic/eui'; -import { getEsQueryConfig } from '@kbn/es-query'; import * as React from 'react'; import { compose } from 'redux'; import { connect } from 'react-redux'; @@ -29,6 +28,7 @@ import { inputsSelectors, State, hostsModel } from '../../store'; import { setAbsoluteRangeDatePicker as dispatchSetAbsoluteRangeDatePicker } from '../../store/inputs/actions'; import { SpyRoute } from '../../utils/route/spy_routes'; import { useKibanaCore } from '../../lib/compose/kibana_core'; +import { esQuery } from '../../../../../../../src/plugins/data/public'; import { HostsEmptyPage } from './hosts_empty_page'; import { navTabsHosts } from './nav_tabs'; @@ -58,7 +58,7 @@ const HostsComponent = React.memo( {({ indicesExist, indexPattern }) => { const filterQuery = convertToBuildEsQuery({ - config: getEsQueryConfig(core.uiSettings), + config: esQuery.getEsQueryConfig(core.uiSettings), indexPattern, queries: [query], filters, diff --git a/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.tsx b/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.tsx index 0fd4e073ebd13c9..0bb4d2cf28c9748 100644 --- a/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/network/ip_details/index.tsx @@ -5,7 +5,6 @@ */ import { EuiHorizontalRule, EuiSpacer, EuiFlexItem } from '@elastic/eui'; -import { getEsQueryConfig } from '@kbn/es-query'; import React, { useCallback, useEffect } from 'react'; import { connect } from 'react-redux'; import { StickyContainer } from 'react-sticky'; @@ -32,6 +31,7 @@ import { setAbsoluteRangeDatePicker as dispatchAbsoluteRangeDatePicker } from '. import { setIpDetailsTablesActivePageToZero as dispatchIpDetailsTablesActivePageToZero } from '../../../store/network/actions'; import { SpyRoute } from '../../../utils/route/spy_routes'; import { NetworkEmptyPage } from '../network_empty_page'; +import { esQuery } from '../../../../../../../../src/plugins/data/public'; import { IPDetailsComponentProps } from './types'; export { getBreadcrumbs } from './utils'; @@ -80,7 +80,7 @@ export const IPDetailsComponent = React.memo( {({ indicesExist, indexPattern }) => { const ip = decodeIpv6(detailName); const filterQuery = convertToBuildEsQuery({ - config: getEsQueryConfig(core.uiSettings), + config: esQuery.getEsQueryConfig(core.uiSettings), indexPattern, queries: [query], filters, diff --git a/x-pack/legacy/plugins/siem/public/pages/network/network.tsx b/x-pack/legacy/plugins/siem/public/pages/network/network.tsx index f7b3cfb4962fcff..20883546c6fa8af 100644 --- a/x-pack/legacy/plugins/siem/public/pages/network/network.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/network/network.tsx @@ -5,7 +5,6 @@ */ import { EuiSpacer } from '@elastic/eui'; -import { getEsQueryConfig } from '@kbn/es-query'; import React from 'react'; import { connect } from 'react-redux'; import { StickyContainer } from 'react-sticky'; @@ -30,6 +29,7 @@ import { navTabsNetwork, NetworkRoutes, NetworkRoutesLoading } from './navigatio import { NetworkEmptyPage } from './network_empty_page'; import * as i18n from './translations'; import { NetworkComponentProps } from './types'; +import { esQuery } from '../../../../../../../src/plugins/data/public'; const KpiNetworkComponentManage = manageQuery(KpiNetworkComponent); const sourceId = 'default'; @@ -53,7 +53,7 @@ const NetworkComponent = React.memo( {({ indicesExist, indexPattern }) => { const filterQuery = convertToBuildEsQuery({ - config: getEsQueryConfig(core.uiSettings), + config: esQuery.getEsQueryConfig(core.uiSettings), indexPattern, queries: [query], filters, diff --git a/x-pack/legacy/plugins/siem/public/pages/network/types.ts b/x-pack/legacy/plugins/siem/public/pages/network/types.ts index e440d0c27e4676b..1941d8f9bfb7bb5 100644 --- a/x-pack/legacy/plugins/siem/public/pages/network/types.ts +++ b/x-pack/legacy/plugins/siem/public/pages/network/types.ts @@ -6,10 +6,9 @@ import { RouteComponentProps } from 'react-router-dom'; import { ActionCreator } from 'typescript-fsa'; -import { Query, esFilters } from 'src/plugins/data/common'; - import { GlobalTimeArgs } from '../../containers/global_time'; import { InputsModelId } from '../../store/inputs/constants'; +import { Query, esFilters } from '../../../../../../../src/plugins/data/public'; export type SetAbsoluteRangeDatePicker = ActionCreator<{ id: InputsModelId; diff --git a/x-pack/legacy/plugins/siem/public/store/inputs/model.ts b/x-pack/legacy/plugins/siem/public/store/inputs/model.ts index 01cf386311d77fc..54409b1f7445484 100644 --- a/x-pack/legacy/plugins/siem/public/store/inputs/model.ts +++ b/x-pack/legacy/plugins/siem/public/store/inputs/model.ts @@ -5,12 +5,11 @@ */ import { Dispatch } from 'redux'; -import { Query } from 'src/plugins/data/common/query'; import { SavedQuery } from 'src/legacy/core_plugins/data/public'; import { Omit } from '../../../common/utility_types'; import { InputsModelId } from './constants'; import { CONSTANTS } from '../../components/url_state/constants'; -import { esFilters } from '../../../../../../../src/plugins/data/public'; +import { Query, esFilters } from '../../../../../../../src/plugins/data/public'; export interface AbsoluteTimeRange { kind: 'absolute'; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/get_filter.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/get_filter.ts index 22ebccbaef6a7ca..01aeb6aa30550ee 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/get_filter.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/get_filter.ts @@ -4,11 +4,15 @@ * you may not use this file except in compliance with the Elastic License. */ -import { buildEsQuery } from '@kbn/es-query'; -import { Query } from 'src/plugins/data/common/query'; import { AlertServices } from '../../../../../alerting/server/types'; import { SignalAlertParams, PartialFilter } from './types'; import { assertUnreachable } from '../../../utils/build_query'; +import { + Query, + esQuery, + esFilters, + IIndexPattern, +} from '../../../../../../../../src/plugins/data/common'; export const getQueryFilter = ( query: string, @@ -19,7 +23,8 @@ export const getQueryFilter = ( const indexPattern = { fields: [], title: index.join(), - }; + } as IIndexPattern; + const queries: Query[] = [{ query, language }]; const config = { allowLeadingWildcards: true, @@ -27,13 +32,12 @@ export const getQueryFilter = ( ignoreFilterIfFieldNotInIndex: false, dateFormatTZ: 'Zulu', }; - const esQuery = buildEsQuery( - indexPattern, - queries, - filters.filter(f => f.meta != null && f.meta.disabled === false), - config + + const enabledFilters = ((filters as unknown) as esFilters.Filter[]).filter( + f => f && !esFilters.isFilterDisabled(f) ); - return esQuery; + + return esQuery.buildEsQuery(indexPattern, queries, enabledFilters, config); }; interface GetFilterArgs { diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/types.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/types.ts index 96a319c944bd90e..1a1d2105e2a07b3 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/types.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/alerts/types.ts @@ -7,7 +7,6 @@ import { get } from 'lodash/fp'; import Hapi from 'hapi'; -import { esFilters } from '../../../../../../../../src/plugins/data/common'; import { SIGNALS_ID } from '../../../../common/constants'; import { Alert, @@ -18,6 +17,7 @@ import { import { AlertsClient } from '../../../../../alerting/server/alerts_client'; import { ActionsClient } from '../../../../../actions/server/actions_client'; import { SearchResponse } from '../../types'; +import { esFilters } from '../../../../../../../../src/plugins/data/common'; export type PartialFilter = Partial; diff --git a/x-pack/legacy/plugins/transform/public/app/lib/kibana/common.ts b/x-pack/legacy/plugins/transform/public/app/lib/kibana/common.ts index 7291eba04057d52..16100089a9e56f9 100644 --- a/x-pack/legacy/plugins/transform/public/app/lib/kibana/common.ts +++ b/x-pack/legacy/plugins/transform/public/app/lib/kibana/common.ts @@ -4,15 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -// @ts-ignore -import { buildEsQuery, getEsQueryConfig } from '@kbn/es-query'; - import { SavedObjectsClientContract, UiSettingsClientContract } from 'src/core/public'; - import { IndexPattern as IndexPatternType, IndexPatterns as IndexPatternsType, } from 'ui/index_patterns'; +import { esQuery } from '../../../../../../../../src/plugins/data/public'; type IndexPatternId = string; type SavedSearchId = string; @@ -106,8 +103,8 @@ export function createSearchItems( const filters = fs.length ? fs : []; - const esQueryConfigs = getEsQueryConfig(config); - combinedQuery = buildEsQuery(indexPattern, [query], filters, esQueryConfigs); + const esQueryConfigs = esQuery.getEsQueryConfig(config); + combinedQuery = esQuery.buildEsQuery(indexPattern || null, [query], filters, esQueryConfigs); } return {