mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
Move @kbn/es-query into data plugin - es-query folder (#50182)
* Move @kbn/es-query into data plugin - es-query * fix eslint issues * Fix PR comments * fix CI * fix Ci * remove extra ts-ignore * fix imports * fix imports * Test importing from data/public and casting to ES Field Types. * Test importing from data/public and casting to ES Field Types.
This commit is contained in:
parent
03e2a683ba
commit
9769be3a28
215 changed files with 1385 additions and 1066 deletions
|
@ -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);
|
||||
});
|
||||
|
||||
});
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -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);
|
||||
});
|
||||
|
||||
});
|
39
packages/kbn-es-query/src/es_query/index.d.ts
vendored
39
packages/kbn-es-query/src/es_query/index.d.ts
vendored
|
@ -1,39 +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.
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
): unknown;
|
||||
export function getEsQueryConfig(config: {
|
||||
get: (name: string) => unknown;
|
||||
}): {
|
||||
allowLeadingWildcards: boolean;
|
||||
queryStringOptions: unknown;
|
||||
ignoreFilterIfFieldNotInIndex: boolean;
|
||||
dateFormatTZ?: string | 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';
|
||||
}
|
1
packages/kbn-es-query/src/index.d.ts
vendored
1
packages/kbn-es-query/src/index.d.ts
vendored
|
@ -17,5 +17,4 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
export * from './es_query';
|
||||
export * from './kuery';
|
||||
|
|
|
@ -18,4 +18,3 @@
|
|||
*/
|
||||
|
||||
export * from './kuery';
|
||||
export * from './es_query';
|
||||
|
|
14
packages/kbn-es-query/src/kuery/ast/ast.d.ts
vendored
14
packages/kbn-es-query/src/kuery/ast/ast.d.ts
vendored
|
@ -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<KueryParseOptions>
|
||||
): KueryNode;
|
||||
|
||||
export function toElasticsearchQuery(node: KueryNode, indexPattern?: any): JsonObject;
|
||||
export function toElasticsearchQuery(
|
||||
node: KueryNode,
|
||||
indexPattern?: any,
|
||||
config?: Record<string, any>,
|
||||
context?: Record<string, any>
|
||||
): JsonObject;
|
||||
|
||||
export function doesKueryExpressionHaveLuceneSyntaxError(expression: string): boolean;
|
||||
|
|
|
@ -17,9 +17,10 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { castEsToKbnFieldTypeName } from '../plugins/data/common';
|
||||
// eslint-disable-next-line max-len
|
||||
import { shouldReadFieldFromDocValues } from '../plugins/data/server';
|
||||
import {
|
||||
shouldReadFieldFromDocValues,
|
||||
castEsToKbnFieldTypeName,
|
||||
} from '../plugins/data/server';
|
||||
|
||||
function stubbedLogstashFields() {
|
||||
return [
|
||||
|
|
|
@ -22,13 +22,12 @@ import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n/react';
|
|||
import classNames from 'classnames';
|
||||
import React, { useState } from 'react';
|
||||
import { CoreStart } from 'src/core/public';
|
||||
import { DataPublicPluginStart } from 'src/plugins/data/public';
|
||||
import { IndexPattern } from '../../index_patterns';
|
||||
import { FilterEditor } from './filter_editor';
|
||||
import { FilterItem } from './filter_item';
|
||||
import { FilterOptions } from './filter_options';
|
||||
import { useKibana, KibanaContextProvider } from '../../../../../../plugins/kibana_react/public';
|
||||
import { esFilters } from '../../../../../../plugins/data/public';
|
||||
import { DataPublicPluginStart, esFilters } from '../../../../../../plugins/data/public';
|
||||
|
||||
interface Props {
|
||||
filters: esFilters.Filter[];
|
||||
|
|
|
@ -22,40 +22,24 @@ import { fieldFormats } from 'ui/registry/field_formats';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
// @ts-ignore
|
||||
import { ObjDefine } from './obj_define';
|
||||
import { FieldFormat } from '../../../../../../plugins/data/common/field_formats';
|
||||
// @ts-ignore
|
||||
import { shortenDottedString } from '../../../../../core_plugins/kibana/common/utils/shorten_dotted_string';
|
||||
import { IndexPattern } from '../index_patterns';
|
||||
import { getNotifications } from '../services';
|
||||
|
||||
import { getKbnFieldType } from '../../../../../../plugins/data/public';
|
||||
|
||||
interface FieldSubType {
|
||||
multi?: { parent: string };
|
||||
nested?: { path: string };
|
||||
}
|
||||
import {
|
||||
FieldFormat,
|
||||
getKbnFieldType,
|
||||
IFieldType,
|
||||
IFieldSubType,
|
||||
} from '../../../../../../plugins/data/public';
|
||||
|
||||
export type FieldSpec = Record<string, any>;
|
||||
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 +56,7 @@ export class Field implements FieldType {
|
|||
sortable?: boolean;
|
||||
visualizable?: boolean;
|
||||
scripted?: boolean;
|
||||
subType?: FieldSubType;
|
||||
subType?: IFieldSubType;
|
||||
displayName?: string;
|
||||
format: any;
|
||||
routes: Record<string, string> = {
|
||||
|
|
|
@ -37,21 +37,18 @@ 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 {
|
||||
export class IndexPattern implements IIndexPattern {
|
||||
[key: string]: any;
|
||||
|
||||
public id?: string;
|
||||
|
|
|
@ -20,12 +20,11 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { CoreStart } from 'src/core/public';
|
||||
import { DataPublicPluginStart } from 'src/plugins/data/public';
|
||||
import { IStorageWrapper } from 'src/plugins/kibana_utils/public';
|
||||
import { KibanaContextProvider } from '../../../../../../../../src/plugins/kibana_react/public';
|
||||
import { SearchBar } from '../../../';
|
||||
import { SearchBarOwnProps } from '.';
|
||||
import { esFilters } from '../../../../../../../plugins/data/public';
|
||||
import { DataPublicPluginStart, esFilters } from '../../../../../../../plugins/data/public';
|
||||
|
||||
interface StatefulSearchBarDeps {
|
||||
core: CoreStart;
|
||||
|
|
|
@ -24,7 +24,6 @@ import React, { Component } from 'react';
|
|||
import ResizeObserver from 'resize-observer-polyfill';
|
||||
import { get, isEqual } from 'lodash';
|
||||
|
||||
import { TimeRange, Query, TimeHistoryContract } from 'src/plugins/data/public';
|
||||
import { IndexPattern, FilterBar } from '../../../../../data/public';
|
||||
import { QueryBarTopRow } from '../../../query';
|
||||
import { SavedQuery, SavedQueryAttributes } from '../index';
|
||||
|
@ -37,7 +36,12 @@ import {
|
|||
KibanaReactContextValue,
|
||||
} from '../../../../../../../plugins/kibana_react/public';
|
||||
import { IDataPluginServices } from '../../../types';
|
||||
import { esFilters } from '../../../../../../../plugins/data/public';
|
||||
import {
|
||||
TimeRange,
|
||||
Query,
|
||||
esFilters,
|
||||
TimeHistoryContract,
|
||||
} from '../../../../../../../plugins/data/public';
|
||||
|
||||
interface SearchBarInjectedDeps {
|
||||
kibana: KibanaReactContextValue<IDataPluginServices>;
|
||||
|
|
|
@ -17,9 +17,8 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { TimeRange } from '../../../../../../plugins/data/public';
|
||||
import { Adapters } from '../../../../../../plugins/inspector/public';
|
||||
import { Query } from '../../../../../../plugins/data/public';
|
||||
import { TimeRange, Query } from '../../../../../../plugins/data/public';
|
||||
|
||||
export { TimeRange, Adapters, Query };
|
||||
export * from '../../../../../../plugins/expressions/public';
|
||||
|
|
|
@ -32,7 +32,6 @@ import {
|
|||
} from 'ui/state_management/app_state';
|
||||
|
||||
import { KbnUrl } from 'ui/url/kbn_url';
|
||||
import { TimeRange, Query } from 'src/plugins/data/public';
|
||||
import { IndexPattern } from 'ui/index_patterns';
|
||||
import { IPrivate } from 'ui/private';
|
||||
import { StaticIndexPattern, SavedQuery } from 'plugins/data';
|
||||
|
@ -42,7 +41,7 @@ import { Subscription } from 'rxjs';
|
|||
import { ViewMode } from '../../../embeddable_api/public/np_ready/public';
|
||||
import { SavedObjectDashboard } from './saved_dashboard/saved_dashboard';
|
||||
import { DashboardAppState, SavedDashboardPanel, ConfirmModalFn } from './types';
|
||||
import { esFilters } from '../../../../../../src/plugins/data/public';
|
||||
import { TimeRange, Query, esFilters } from '../../../../../../src/plugins/data/public';
|
||||
|
||||
import { DashboardAppController } from './dashboard_app_controller';
|
||||
|
||||
|
|
|
@ -27,9 +27,8 @@ import { migrateLegacyQuery } from 'ui/utils/migrate_legacy_query';
|
|||
import { Moment } from 'moment';
|
||||
|
||||
import { DashboardContainer } from 'src/legacy/core_plugins/dashboard_embeddable_container/public/np_ready/public';
|
||||
import { Query } from 'src/plugins/data/public';
|
||||
import { ViewMode } from '../../../../../../src/plugins/embeddable/public';
|
||||
import { esFilters } from '../../../../../../src/plugins/data/public';
|
||||
import { Query, esFilters } from '../../../../../../src/plugins/data/public';
|
||||
|
||||
import { getAppStateDefaults, migrateAppState } from './lib';
|
||||
import { convertPanelStateToSavedDashboardPanel } from './lib/embeddable_saved_object_converters';
|
||||
|
|
|
@ -30,6 +30,7 @@ import {
|
|||
generateFilters,
|
||||
getTime,
|
||||
Query,
|
||||
IFieldType,
|
||||
} from '../../../../../../plugins/data/public';
|
||||
import {
|
||||
APPLY_FILTER_TRIGGER,
|
||||
|
@ -66,7 +67,7 @@ interface SearchScope extends ng.IScope {
|
|||
removeColumn?: (column: string) => void;
|
||||
addColumn?: (column: string) => void;
|
||||
moveColumn?: (column: string, index: number) => void;
|
||||
filter?: (field: { name: string; scripted: boolean }, value: string[], operator: string) => void;
|
||||
filter?: (field: IFieldType, value: string[], operator: string) => void;
|
||||
hits?: any[];
|
||||
indexPattern?: IndexPattern;
|
||||
totalHitCount?: number;
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
import _ from 'lodash';
|
||||
import expect from '@kbn/expect';
|
||||
import { fieldFormats } from 'ui/registry/field_formats';
|
||||
import { FieldFormat } from '../../../../../../plugins/data/common/field_formats';
|
||||
import { npStart } from 'ui/new_platform';
|
||||
import { FieldFormat } from '../../../../../../plugins/data/public';
|
||||
|
||||
const config = npStart.core.uiSettings;
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ import {
|
|||
BoolFormat,
|
||||
SourceFormat,
|
||||
StaticLookupFormat
|
||||
} from '../../../../../plugins/data/common';
|
||||
} from '../../../../../plugins/data/server';
|
||||
|
||||
export function registerFieldFormats(server) {
|
||||
server.registerFieldFormat(UrlFormat);
|
||||
|
|
|
@ -17,15 +17,13 @@
|
|||
* 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, 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, Query } from '../../../../../plugins/data/public';
|
||||
|
||||
interface Stats {
|
||||
cacheCount: number;
|
||||
|
@ -74,7 +72,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);
|
||||
|
@ -85,7 +83,7 @@ export function getTimelionRequestHandler(dependencies: TimelionVisualizationDep
|
|||
sheet: [expression],
|
||||
extended: {
|
||||
es: {
|
||||
filter: buildEsQuery(undefined, query, filters, esQueryConfigs),
|
||||
filter: esQuery.buildEsQuery(null, query, filters, esQueryConfigs),
|
||||
},
|
||||
},
|
||||
time: {
|
||||
|
|
|
@ -35,7 +35,7 @@ import {
|
|||
EuiFormRow,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../../plugins/data/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../../plugins/data/public';
|
||||
import { METRIC_TYPES } from '../../../common/metric_types';
|
||||
|
||||
export const FilterRatioAgg = props => {
|
||||
|
|
|
@ -34,7 +34,7 @@ import {
|
|||
EuiFormRow,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../../plugins/data/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../../plugins/data/public';
|
||||
import { Percentiles, newPercentile } from './percentile_ui';
|
||||
|
||||
const RESTRICT_FIELDS = [KBN_FIELD_TYPES.NUMBER];
|
||||
|
|
|
@ -36,7 +36,7 @@ import {
|
|||
EuiSpacer,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../../../plugins/data/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../../../plugins/data/public';
|
||||
|
||||
const RESTRICT_FIELDS = [KBN_FIELD_TYPES.NUMBER];
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ import {
|
|||
EuiSpacer,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../../plugins/data/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../../plugins/data/public';
|
||||
import { METRIC_TYPES } from '../../../common/metric_types';
|
||||
|
||||
export function StandardAgg(props) {
|
||||
|
|
|
@ -36,7 +36,7 @@ import {
|
|||
EuiSpacer,
|
||||
} from '@elastic/eui';
|
||||
import { injectI18n, FormattedMessage } from '@kbn/i18n/react';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../../plugins/data/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../../plugins/data/public';
|
||||
|
||||
const RESTRICT_FIELDS = [KBN_FIELD_TYPES.NUMBER];
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ import {
|
|||
EuiFormRow,
|
||||
} from '@elastic/eui';
|
||||
import { injectI18n, FormattedMessage } from '@kbn/i18n/react';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../../plugins/data/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../../plugins/data/public';
|
||||
import { PANEL_TYPES } from '../../../common/panel_types';
|
||||
|
||||
const isFieldTypeEnabled = (fieldRestrictions, fieldType) =>
|
||||
|
|
|
@ -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/server';
|
||||
|
||||
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) {
|
||||
|
|
|
@ -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/server';
|
||||
|
||||
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)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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/server';
|
||||
|
||||
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);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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/server';
|
||||
|
||||
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);
|
||||
|
|
|
@ -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/server';
|
||||
|
||||
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);
|
||||
|
|
|
@ -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/server';
|
||||
|
||||
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);
|
||||
|
|
|
@ -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/server';
|
||||
|
||||
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)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -18,9 +18,7 @@
|
|||
*/
|
||||
|
||||
import { timefilter } from 'ui/timefilter';
|
||||
|
||||
import { buildEsQuery, getEsQueryConfig } from '@kbn/es-query';
|
||||
import { esFilters, TimeRange, Query } from '../../../../plugins/data/public';
|
||||
import { esFilters, esQuery, TimeRange, Query } from '../../../../plugins/data/public';
|
||||
|
||||
// @ts-ignore
|
||||
import { VegaParser } from './data_model/vega_parser';
|
||||
|
@ -50,8 +48,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();
|
||||
|
|
|
@ -32,7 +32,7 @@ import { AggGroupNames } from '../vis/editors/default/agg_groups';
|
|||
import { writeParams } from './agg_params';
|
||||
import { AggConfigs } from './agg_configs';
|
||||
import { Schema } from '../vis/editors/default/schemas';
|
||||
import { ContentType } from '../../../../plugins/data/common';
|
||||
import { ContentType } from '../../../../plugins/data/public';
|
||||
|
||||
// @ts-ignore
|
||||
import { fieldFormats } from '../registry/field_formats';
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
import { AggParamType } from '../param_types/agg';
|
||||
import { AggConfig } from '../../vis';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
|
||||
import { AggType, AggTypeConfig } from '../agg_type';
|
||||
|
||||
export type IBucketAggConfig = AggConfig;
|
||||
|
|
|
@ -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, [], '');
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
import moment from 'moment';
|
||||
import { createFilterDateRange } from './date_range';
|
||||
import { DateFormat } from '../../../../../../plugins/data/common';
|
||||
import { DateFormat } from '../../../../../../plugins/data/public';
|
||||
import { AggConfigs } from '../../agg_configs';
|
||||
import { BUCKET_TYPES } from '../bucket_agg_types';
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
import { createFilterHistogram } from './histogram';
|
||||
import { AggConfigs } from '../../agg_configs';
|
||||
import { BUCKET_TYPES } from '../bucket_agg_types';
|
||||
import { BytesFormat } from '../../../../../../plugins/data/common';
|
||||
import { BytesFormat } from '../../../../../../plugins/data/public';
|
||||
|
||||
jest.mock('ui/new_platform');
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
import { createFilterIpRange } from './ip_range';
|
||||
import { AggConfigs } from '../../agg_configs';
|
||||
import { IpFormat } from '../../../../../../plugins/data/common';
|
||||
import { IpFormat } from '../../../../../../plugins/data/public';
|
||||
import { BUCKET_TYPES } from '../bucket_agg_types';
|
||||
|
||||
jest.mock('ui/new_platform');
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
import { createFilterRange } from './range';
|
||||
import { BytesFormat } from '../../../../../../plugins/data/common';
|
||||
import { BytesFormat } from '../../../../../../plugins/data/public';
|
||||
import { AggConfigs } from '../../agg_configs';
|
||||
import { BUCKET_TYPES } from '../bucket_agg_types';
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ import { writeParams } from '../agg_params';
|
|||
import { AggConfigs } from '../agg_configs';
|
||||
import { isMetricAggType } from '../metrics/metric_agg_type';
|
||||
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
|
||||
|
||||
// @ts-ignore
|
||||
import { TimeBuckets } from '../../time_buckets';
|
||||
|
|
|
@ -23,14 +23,13 @@ import { npStart } from 'ui/new_platform';
|
|||
import { BUCKET_TYPES } from './bucket_agg_types';
|
||||
import { BucketAggType, IBucketAggConfig } from './_bucket_agg_type';
|
||||
import { createFilterDateRange } from './create_filter/date_range';
|
||||
import { FieldFormat } from '../../../../../plugins/data/common/field_formats';
|
||||
import { FieldFormat, KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
|
||||
import { DateRangesParamEditor } from '../../vis/editors/default/controls/date_ranges';
|
||||
|
||||
// @ts-ignore
|
||||
import { fieldFormats } from '../../registry/field_formats';
|
||||
// @ts-ignore
|
||||
import { dateRange } from '../../utils/date_range';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common';
|
||||
|
||||
const dateRangeTitle = i18n.translate('common.ui.aggTypes.buckets.dateRangeTitle', {
|
||||
defaultMessage: 'Date Range',
|
||||
|
|
|
@ -23,12 +23,11 @@ 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 { Storage } from '../../../../../plugins/kibana_utils/public';
|
||||
import { getQueryLog } from '../../../../../plugins/data/public';
|
||||
import { getQueryLog, esQuery } from '../../../../../plugins/data/public';
|
||||
|
||||
const config = chrome.getUiSettingsClient();
|
||||
const storage = new Storage(window.localStorage);
|
||||
|
@ -68,7 +67,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
|
||||
|
|
|
@ -26,7 +26,7 @@ import { IsFilteredByCollarParamEditor } from '../../vis/editors/default/control
|
|||
import { PrecisionParamEditor } from '../../vis/editors/default/controls/precision';
|
||||
import { geohashColumns } from '../../utils/decode_geo_hash';
|
||||
import { AggGroupNames } from '../../vis/editors/default/agg_groups';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
|
||||
|
||||
// @ts-ignore
|
||||
import { geoContains, scaleBounds } from '../../utils/geo_utils';
|
||||
|
|
|
@ -24,7 +24,7 @@ import { AggConfigOptions } from 'ui/agg_types/agg_config';
|
|||
|
||||
import { BucketAggType } from './_bucket_agg_type';
|
||||
import { BUCKET_TYPES } from './bucket_agg_types';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
|
||||
|
||||
const geotileGridTitle = i18n.translate('common.ui.aggTypes.buckets.geotileGridTitle', {
|
||||
defaultMessage: 'Geotile',
|
||||
|
|
|
@ -28,7 +28,7 @@ import { NumberIntervalParamEditor } from '../../vis/editors/default/controls/nu
|
|||
import { MinDocCountParamEditor } from '../../vis/editors/default/controls/min_doc_count';
|
||||
import { HasExtendedBoundsParamEditor } from '../../vis/editors/default/controls/has_extended_bounds';
|
||||
import { ExtendedBoundsParamEditor } from '../../vis/editors/default/controls/extended_bounds';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
|
||||
import { BUCKET_TYPES } from './bucket_agg_types';
|
||||
|
||||
export interface AutoBounds {
|
||||
|
|
|
@ -24,13 +24,12 @@ import { IpRangeTypeParamEditor } from '../../vis/editors/default/controls/ip_ra
|
|||
import { IpRangesParamEditor } from '../../vis/editors/default/controls/ip_ranges';
|
||||
// @ts-ignore
|
||||
import { fieldFormats } from '../../registry/field_formats';
|
||||
import { FieldFormat } from '../../../../../plugins/data/common/field_formats';
|
||||
import { FieldFormat, KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
|
||||
import { ipRange } from '../../utils/ip_range';
|
||||
import { BUCKET_TYPES } from './bucket_agg_types';
|
||||
|
||||
// @ts-ignore
|
||||
import { createFilterIpRange } from './create_filter/ip_range';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common';
|
||||
|
||||
const ipRangeTitle = i18n.translate('common.ui.aggTypes.buckets.ipRangeTitle', {
|
||||
defaultMessage: 'IPv4 Range',
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
import { AggConfigs } from '../agg_configs';
|
||||
import { BUCKET_TYPES } from './bucket_agg_types';
|
||||
import { NumberFormat } from '../../../../../plugins/data/common/';
|
||||
import { NumberFormat } from '../../../../../plugins/data/public';
|
||||
|
||||
jest.mock('ui/new_platform');
|
||||
|
||||
|
|
|
@ -20,14 +20,13 @@
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { IBucketAggConfig } from './_bucket_agg_type';
|
||||
import { BucketAggType } from './_bucket_agg_type';
|
||||
import { FieldFormat } from '../../../../../plugins/data/common/field_formats';
|
||||
import { FieldFormat, KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
|
||||
import { RangeKey } from './range_key';
|
||||
import { RangesEditor } from './range_editor';
|
||||
|
||||
// @ts-ignore
|
||||
import { createFilterRange } from './create_filter/range';
|
||||
import { BUCKET_TYPES } from './bucket_agg_types';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common';
|
||||
|
||||
const keyCaches = new WeakMap();
|
||||
const formats = new WeakMap();
|
||||
|
|
|
@ -23,7 +23,7 @@ import { BucketAggType, BucketAggParam } from './_bucket_agg_type';
|
|||
import { createFilterTerms } from './create_filter/terms';
|
||||
import { isStringType, migrateIncludeExcludeFormat } from './migrate_include_exclude_format';
|
||||
import { BUCKET_TYPES } from './bucket_agg_types';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
|
||||
|
||||
const significantTermsTitle = i18n.translate('common.ui.aggTypes.buckets.significantTermsTitle', {
|
||||
defaultMessage: 'Significant Terms',
|
||||
|
|
|
@ -23,7 +23,6 @@ import { SearchSource } from 'ui/courier';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { BucketAggType, BucketAggParam } from './_bucket_agg_type';
|
||||
import { BUCKET_TYPES } from './bucket_agg_types';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common';
|
||||
import { AggConfigOptions } from '../agg_config';
|
||||
import { IBucketAggConfig } from './_bucket_agg_type';
|
||||
import {
|
||||
|
@ -39,10 +38,10 @@ import { OrderByParamEditor, aggFilter } from '../../vis/editors/default/control
|
|||
import { SizeParamEditor } from '../../vis/editors/default/controls/size';
|
||||
import { MissingBucketParamEditor } from '../../vis/editors/default/controls/missing_bucket';
|
||||
import { OtherBucketParamEditor } from '../../vis/editors/default/controls/other_bucket';
|
||||
import { ContentType } from '../../../../../plugins/data/common';
|
||||
import { AggConfigs } from '../agg_configs';
|
||||
|
||||
import { Adapters } from '../../../../../plugins/inspector/public';
|
||||
import { ContentType, KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
|
||||
|
||||
// @ts-ignore
|
||||
import { Schemas } from '../../vis/editors/default/schemas';
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { MetricAggType } from './metric_agg_type';
|
||||
import { METRIC_TYPES } from './metric_agg_types';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
|
||||
|
||||
const averageTitle = i18n.translate('common.ui.aggTypes.metrics.averageTitle', {
|
||||
defaultMessage: 'Average',
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { MetricAggType } from './metric_agg_type';
|
||||
import { METRIC_TYPES } from './metric_agg_types';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
|
||||
|
||||
const geoBoundsTitle = i18n.translate('common.ui.aggTypes.metrics.geoBoundsTitle', {
|
||||
defaultMessage: 'Geo Bounds',
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { MetricAggType } from './metric_agg_type';
|
||||
import { METRIC_TYPES } from './metric_agg_types';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
|
||||
|
||||
const geoCentroidTitle = i18n.translate('common.ui.aggTypes.metrics.geoCentroidTitle', {
|
||||
defaultMessage: 'Geo Centroid',
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { MetricAggType } from './metric_agg_type';
|
||||
import { METRIC_TYPES } from './metric_agg_types';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
|
||||
|
||||
const maxTitle = i18n.translate('common.ui.aggTypes.metrics.maxTitle', {
|
||||
defaultMessage: 'Max',
|
||||
|
|
|
@ -22,7 +22,7 @@ import { METRIC_TYPES } from './metric_agg_types';
|
|||
|
||||
// @ts-ignore
|
||||
import { percentilesMetricAgg } from './percentiles';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
|
||||
|
||||
const medianTitle = i18n.translate('common.ui.aggTypes.metrics.medianTitle', {
|
||||
defaultMessage: 'Median',
|
||||
|
|
|
@ -25,7 +25,7 @@ import { METRIC_TYPES } from './metric_agg_types';
|
|||
|
||||
// @ts-ignore
|
||||
import { fieldFormats } from '../../registry/field_formats';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
|
||||
|
||||
export type IMetricAggConfig = AggConfig;
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { MetricAggType } from './metric_agg_type';
|
||||
import { METRIC_TYPES } from './metric_agg_types';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
|
||||
|
||||
const minTitle = i18n.translate('common.ui.aggTypes.metrics.minTitle', {
|
||||
defaultMessage: 'Min',
|
||||
|
|
|
@ -26,7 +26,7 @@ import { getPercentileValue } from './percentiles_get_value';
|
|||
import { METRIC_TYPES } from './metric_agg_types';
|
||||
// @ts-ignore
|
||||
import { fieldFormats } from '../../registry/field_formats';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
|
||||
|
||||
// required by the values editor
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ import { i18n } from '@kbn/i18n';
|
|||
|
||||
import { IMetricAggConfig, MetricAggType } from './metric_agg_type';
|
||||
import { METRIC_TYPES } from './metric_agg_types';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
|
||||
|
||||
import { getResponseAggConfigClass, IResponseAggConfig } from './lib/get_response_agg_config_class';
|
||||
import { getPercentileValue } from './percentiles_get_value';
|
||||
|
|
|
@ -22,7 +22,7 @@ import { i18n } from '@kbn/i18n';
|
|||
import { MetricAggType } from './metric_agg_type';
|
||||
import { METRIC_TYPES } from './metric_agg_types';
|
||||
import { getResponseAggConfigClass, IResponseAggConfig } from './lib/get_response_agg_config_class';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
|
||||
|
||||
interface ValProp {
|
||||
valProp: string[];
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { MetricAggType } from './metric_agg_type';
|
||||
import { METRIC_TYPES } from './metric_agg_types';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
|
||||
|
||||
const sumTitle = i18n.translate('common.ui.aggTypes.metrics.sumTitle', {
|
||||
defaultMessage: 'Sum',
|
||||
|
|
|
@ -21,7 +21,7 @@ import { dropRight, last } from 'lodash';
|
|||
import { topHitMetricAgg } from './top_hit';
|
||||
import { AggConfigs } from '../agg_configs';
|
||||
import { IMetricAggConfig } from './metric_agg_type';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
|
||||
|
||||
jest.mock('ui/new_platform');
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ import { TopSizeParamEditor } from '../../vis/editors/default/controls/top_size'
|
|||
import { TopAggregateParamEditor } from '../../vis/editors/default/controls/top_aggregate';
|
||||
import { aggTypeFieldFilters } from '../param_types/filter';
|
||||
import { METRIC_TYPES } from './metric_agg_types';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/common';
|
||||
import { KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
|
||||
|
||||
// @ts-ignore
|
||||
import { wrapWithInlineComp } from '../buckets/inline_comp_wrapper';
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
import { BaseParamType } from './base';
|
||||
import { FieldParamType } from './field';
|
||||
import { ES_FIELD_TYPES, KBN_FIELD_TYPES } from '../../../../../plugins/data/common';
|
||||
import { ES_FIELD_TYPES, KBN_FIELD_TYPES } from '../../../../../plugins/data/public';
|
||||
|
||||
jest.mock('ui/new_platform');
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { isValidEsInterval } from '../../../core_plugins/data/common';
|
||||
import { isValidEsInterval } from '../../../core_plugins/data/public';
|
||||
import { leastCommonInterval } from '../vis/lib/least_common_interval';
|
||||
|
||||
/**
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -22,7 +22,7 @@ import { identity } from 'lodash';
|
|||
import { AggConfig, Vis } from 'ui/vis';
|
||||
import { SerializedFieldFormat } from 'src/plugins/expressions/public';
|
||||
|
||||
import { FieldFormat } from '../../../../../../plugins/data/common/field_formats';
|
||||
import { FieldFormat } from '../../../../../../plugins/data/public';
|
||||
|
||||
import { tabifyGetColumns } from '../../../agg_response/tabify/_get_columns';
|
||||
import chrome from '../../../chrome';
|
||||
|
|
|
@ -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 '../../index_patterns/mocks';
|
||||
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);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
|
@ -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<string, any>;
|
||||
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],
|
||||
},
|
||||
};
|
||||
}
|
|
@ -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' },
|
||||
});
|
||||
});
|
||||
});
|
|
@ -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<string, any>,
|
||||
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),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
65
src/plugins/data/common/es_query/es_query/es_query_dsl.ts
Normal file
65
src/plugins/data/common/es_query/es_query/es_query_dsl.ts
Normal file
|
@ -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<string, string>;
|
||||
}
|
||||
|
||||
export interface DslTermQuery {
|
||||
term: Record<string, string>;
|
||||
}
|
||||
|
||||
export type DslQuery =
|
||||
| DslRangeQuery
|
||||
| DslMatchQuery
|
||||
| DslQueryStringQuery
|
||||
| DslMatchAllQuery
|
||||
| DslTermQuery;
|
||||
|
||||
export const isEsQueryString = (query: any): query is DslQueryStringQuery =>
|
||||
has(query, 'query_string.query');
|
|
@ -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);
|
||||
});
|
||||
});
|
|
@ -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) {
|
||||
import { IIndexPattern, IFieldType } from '../../index_patterns';
|
||||
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;
|
||||
}
|
||||
return indexPattern.fields.some(field => field.name === filter.meta.key);
|
||||
return indexPattern.fields.some((field: IFieldType) => field.name === filter.meta.key);
|
||||
}
|
148
src/plugins/data/common/es_query/es_query/from_filters.test.ts
Normal file
148
src/plugins/data/common/es_query/es_query/from_filters.test.ts
Normal file
|
@ -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 '../../index_patterns/mocks';
|
||||
|
||||
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);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -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)),
|
||||
};
|
||||
}
|
||||
};
|
|
@ -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';
|
||||
import { buildQueryFromKuery } from './from_kuery';
|
||||
import { fromKueryExpression, toElasticsearchQuery } from '@kbn/es-query';
|
||||
import { IIndexPattern } from '../../index_patterns';
|
||||
import { fields } from '../../index_patterns/mocks';
|
||||
import { Query } from '../../query/types';
|
||||
|
||||
describe('build query', function () {
|
||||
describe('buildQueryFromKuery', function () {
|
||||
it('should return the parameters of an Elasticsearch bool query', function () {
|
||||
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,40 +37,14 @@ 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' },
|
||||
];
|
||||
|
||||
const expectedESQueries = queries.map(
|
||||
(query) => {
|
||||
return toElasticsearchQuery(fromKueryExpression(query.query), indexPattern);
|
||||
}
|
||||
);
|
||||
|
||||
const result = buildQueryFromKuery(indexPattern, queries, true);
|
||||
|
||||
expect(result.filter).to.eql(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' }];
|
||||
|
||||
const expectedESQueries = queries.map(query => {
|
||||
return toElasticsearchQuery(fromKueryExpression(query.query), indexPattern, { dateFormatTZ: 'America/Phoenix' });
|
||||
});
|
||||
|
||||
const result = buildQueryFromKuery(indexPattern, queries, true, 'America/Phoenix');
|
||||
|
||||
expect(result.filter).to.eql(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' }];
|
||||
] as Query[];
|
||||
|
||||
const expectedESQueries = queries.map(query => {
|
||||
return toElasticsearchQuery(fromKueryExpression(query.query), indexPattern);
|
||||
|
@ -73,9 +52,33 @@ describe('build query', function () {
|
|||
|
||||
const result = buildQueryFromKuery(indexPattern, queries, true);
|
||||
|
||||
expect(result.filter).to.eql(expectedESQueries);
|
||||
expect(result.filter).toEqual(expectedESQueries);
|
||||
});
|
||||
|
||||
});
|
||||
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',
|
||||
});
|
||||
});
|
||||
|
||||
const result = buildQueryFromKuery(indexPattern, queries, true, 'America/Phoenix');
|
||||
|
||||
expect(result.filter).toEqual(expectedESQueries);
|
||||
});
|
||||
|
||||
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).toEqual(expectedESQueries);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -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: KueryNode[],
|
||||
config: Record<string, any> = {}
|
||||
) {
|
||||
const compoundQueryAST: KueryNode = nodeTypes.function.buildNode('and', queryASTs);
|
||||
const kueryQuery: Record<string, any> = toElasticsearchQuery(
|
||||
compoundQueryAST,
|
||||
indexPattern,
|
||||
config
|
||||
);
|
||||
|
||||
return {
|
||||
must: [],
|
||||
filter: [],
|
||||
should: [],
|
||||
must_not: [],
|
||||
...kueryQuery.bool
|
||||
...kueryQuery.bool,
|
||||
};
|
||||
}
|
|
@ -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);
|
||||
});
|
||||
});
|
|
@ -16,19 +16,23 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import _ 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<string, any>,
|
||||
dateFormatTZ?: string
|
||||
) {
|
||||
const combinedQueries = (queries || []).map(query => {
|
||||
const queryDsl = luceneStringToDsl(query.query);
|
||||
|
||||
return decorateQuery(queryDsl, queryStringOptions, dateFormatTZ);
|
||||
});
|
||||
|
||||
return {
|
||||
must: [].concat(combinedQueries),
|
||||
must: combinedQueries,
|
||||
filter: [],
|
||||
should: [],
|
||||
must_not: [],
|
|
@ -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');
|
||||
});
|
||||
});
|
|
@ -17,10 +17,22 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
export function getEsQueryConfig(config) {
|
||||
import { EsQueryConfig } from './build_es_query';
|
||||
|
||||
interface KibanaConfig {
|
||||
get<T>(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;
|
||||
}
|
|
@ -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';
|
|
@ -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);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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 { 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 query;
|
||||
}
|
|
@ -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);
|
||||
});
|
||||
});
|
65
src/plugins/data/common/es_query/es_query/migrate_filter.ts
Normal file
65
src/plugins/data/common/es_query/es_query/migrate_filter.ts
Normal file
|
@ -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<string, any> = 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;
|
||||
}
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
import { Filter, FilterMeta } from './meta_filter';
|
||||
import { IndexPattern, Field } from '../../types';
|
||||
import { IIndexPattern, IFieldType } from '../../index_patterns';
|
||||
|
||||
export type ExistsFilterMeta = FilterMeta;
|
||||
|
||||
|
@ -33,7 +33,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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -18,16 +18,16 @@
|
|||
*/
|
||||
|
||||
import { buildInlineScriptForPhraseFilter, buildPhraseFilter } from './phrase_filter';
|
||||
import { IndexPattern } from '../../types';
|
||||
import { getField } from '../__tests__/fields_mock';
|
||||
import { getField } from '../../index_patterns/mocks';
|
||||
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', () => {
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
import { get, isPlainObject } from 'lodash';
|
||||
import { Filter, FilterMeta } from './meta_filter';
|
||||
import { IndexPattern, Field } from '../../types';
|
||||
import { IIndexPattern, IFieldType } from '../../index_patterns';
|
||||
|
||||
export type PhraseFilterMeta = FilterMeta & {
|
||||
params?: {
|
||||
|
@ -51,7 +51,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 +69,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 +92,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 +110,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;
|
||||
|
|
|
@ -18,8 +18,9 @@
|
|||
*/
|
||||
|
||||
import { Filter, FilterMeta } from './meta_filter';
|
||||
import { Field, IndexPattern } from '../../types';
|
||||
import { getPhraseScript } from './phrase_filter';
|
||||
import { FILTERS } from './index';
|
||||
import { IIndexPattern, IFieldType } from '../../index_patterns';
|
||||
|
||||
export type PhrasesFilterMeta = FilterMeta & {
|
||||
params: string[]; // The unformatted values
|
||||
|
@ -31,16 +32,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(', ');
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -19,16 +19,16 @@
|
|||
|
||||
import { each } from 'lodash';
|
||||
import { buildRangeFilter, RangeFilter } from './range_filter';
|
||||
import { IndexPattern, Field } from '../../types';
|
||||
import { getField } from '../__tests__/fields_mock';
|
||||
import { getField } from '../../index_patterns/mocks';
|
||||
import { IIndexPattern, IFieldType } from '../../index_patterns';
|
||||
|
||||
describe('Range filter builder', () => {
|
||||
let indexPattern: IndexPattern;
|
||||
let indexPattern: IIndexPattern;
|
||||
|
||||
beforeEach(() => {
|
||||
indexPattern = {
|
||||
id: 'id',
|
||||
};
|
||||
} as IIndexPattern;
|
||||
});
|
||||
|
||||
it('should be a function', () => {
|
||||
|
@ -118,7 +118,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 +148,7 @@ describe('Range filter builder', () => {
|
|||
});
|
||||
|
||||
describe('when given params where both sides are infinite', () => {
|
||||
let field: Field;
|
||||
let field: IFieldType;
|
||||
let filter: RangeFilter;
|
||||
|
||||
beforeEach(() => {
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
import { map, reduce, mapValues, get, keys, pick } from 'lodash';
|
||||
import { Filter, FilterMeta } from './meta_filter';
|
||||
import { Field, IndexPattern } from '../../types';
|
||||
import { IIndexPattern, IFieldType } from '../../index_patterns';
|
||||
|
||||
const OPERANDS_IN_RANGE = 2;
|
||||
|
||||
|
@ -84,18 +84,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 +139,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,
|
||||
|
|
|
@ -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 };
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue