mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
filter types (#111269)
This commit is contained in:
parent
b59e3ff460
commit
1a577dfbfa
96 changed files with 501 additions and 634 deletions
|
@ -41,8 +41,10 @@ describe('build query', () => {
|
|||
{ query: 'bar:baz', language: 'lucene' },
|
||||
] as Query[];
|
||||
const filters = {
|
||||
match: {
|
||||
a: 'b',
|
||||
query: {
|
||||
match: {
|
||||
a: 'b',
|
||||
},
|
||||
},
|
||||
meta: {
|
||||
alias: '',
|
||||
|
@ -80,8 +82,10 @@ describe('build query', () => {
|
|||
it('should accept queries and filters as either single objects or arrays', () => {
|
||||
const queries = { query: 'extension:jpg', language: 'lucene' } as Query;
|
||||
const filters = {
|
||||
match: {
|
||||
a: 'b',
|
||||
query: {
|
||||
match: {
|
||||
a: 'b',
|
||||
},
|
||||
},
|
||||
meta: {
|
||||
alias: '',
|
||||
|
@ -118,12 +122,14 @@ describe('build query', () => {
|
|||
it('should remove match_all clauses', () => {
|
||||
const filters = [
|
||||
{
|
||||
match_all: {},
|
||||
query: { match_all: {} },
|
||||
meta: { type: 'match_all' },
|
||||
} as MatchAllFilter,
|
||||
{
|
||||
match: {
|
||||
a: 'b',
|
||||
query: {
|
||||
match: {
|
||||
a: 'b',
|
||||
},
|
||||
},
|
||||
meta: {
|
||||
alias: '',
|
||||
|
@ -163,7 +169,7 @@ describe('build query', () => {
|
|||
{ query: '@timestamp:"2019-03-23T13:18:00"', language: 'kuery' },
|
||||
{ query: '@timestamp:"2019-03-23T13:18:00"', language: 'lucene' },
|
||||
] as Query[];
|
||||
const filters = [{ match_all: {}, meta: { type: 'match_all' } } as MatchAllFilter];
|
||||
const filters = [{ query: { match_all: {} }, meta: { type: 'match_all' } } as MatchAllFilter];
|
||||
const config = {
|
||||
allowLeadingWildcards: true,
|
||||
queryStringOptions: {},
|
||||
|
|
|
@ -31,11 +31,11 @@ describe('build query', () => {
|
|||
test('should transform an array of kibana filters into ES queries combined in the bool clauses', () => {
|
||||
const filters = [
|
||||
{
|
||||
match_all: {},
|
||||
query: { match_all: {} },
|
||||
meta: { type: 'match_all' },
|
||||
} as MatchAllFilter,
|
||||
{
|
||||
exists: { field: 'foo' },
|
||||
query: { exists: { field: 'foo' } },
|
||||
meta: { type: 'exists' },
|
||||
} as ExistsFilter,
|
||||
] as Filter[];
|
||||
|
@ -50,7 +50,7 @@ describe('build query', () => {
|
|||
test('should remove disabled filters', () => {
|
||||
const filters = [
|
||||
{
|
||||
match_all: {},
|
||||
query: { match_all: {} },
|
||||
meta: { type: 'match_all', negate: true, disabled: true },
|
||||
} as MatchAllFilter,
|
||||
] as Filter[];
|
||||
|
@ -70,7 +70,7 @@ describe('build query', () => {
|
|||
test('should place negated filters in the must_not clause', () => {
|
||||
const filters = [
|
||||
{
|
||||
match_all: {},
|
||||
query: { match_all: {} },
|
||||
meta: { type: 'match_all', negate: true },
|
||||
} as MatchAllFilter,
|
||||
] as Filter[];
|
||||
|
@ -104,10 +104,10 @@ describe('build query', () => {
|
|||
test('should migrate deprecated match syntax', () => {
|
||||
const filters = [
|
||||
{
|
||||
query: { match: { extension: { query: 'foo', type: 'phrase' } } },
|
||||
match: { extension: { query: 'foo', type: 'phrase' } },
|
||||
meta: { type: 'phrase' },
|
||||
},
|
||||
] as Filter[];
|
||||
] as unknown as Filter[];
|
||||
|
||||
const expectedESQueries = [
|
||||
{
|
||||
|
@ -137,7 +137,7 @@ describe('build query', () => {
|
|||
test('should wrap filters targeting nested fields in a nested query', () => {
|
||||
const filters = [
|
||||
{
|
||||
exists: { field: 'nestedField.child' },
|
||||
query: { exists: { field: 'nestedField.child' } },
|
||||
meta: { type: 'exists', alias: '', disabled: false, negate: false },
|
||||
},
|
||||
];
|
||||
|
|
|
@ -35,12 +35,7 @@ const filterNegate = (reverse: boolean) => (filter: Filter) => {
|
|||
* @return {Object} the query version of that filter
|
||||
*/
|
||||
const translateToQuery = (filter: Partial<Filter>): estypes.QueryDslQueryContainer => {
|
||||
if (filter.query) {
|
||||
return filter.query as estypes.QueryDslQueryContainer;
|
||||
}
|
||||
|
||||
// TODO: investigate what's going on here! What does this mean for filters that don't have a query!
|
||||
return filter as estypes.QueryDslQueryContainer;
|
||||
return filter.query || filter;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,11 +25,13 @@ describe('handleNestedFilter', function () {
|
|||
meta: {
|
||||
index: 'logstash-*',
|
||||
},
|
||||
nested: {
|
||||
path: 'nestedField',
|
||||
query: {
|
||||
match_phrase: {
|
||||
'nestedField.child': 'foo',
|
||||
query: {
|
||||
nested: {
|
||||
path: 'nestedField',
|
||||
query: {
|
||||
match_phrase: {
|
||||
'nestedField.child': 'foo',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -65,10 +67,8 @@ describe('handleNestedFilter', function () {
|
|||
// for example, we don't support query_string queries
|
||||
const filter = buildQueryFilter(
|
||||
{
|
||||
query: {
|
||||
query_string: {
|
||||
query: 'response:200',
|
||||
},
|
||||
query_string: {
|
||||
query: 'response:200',
|
||||
},
|
||||
},
|
||||
'logstash-*',
|
||||
|
|
|
@ -29,9 +29,11 @@ export const handleNestedFilter = (filter: Filter, indexPattern?: IndexPatternBa
|
|||
|
||||
return {
|
||||
meta: filter.meta,
|
||||
nested: {
|
||||
path: field.subType.nested.path,
|
||||
query: query.query || query,
|
||||
query: {
|
||||
nested: {
|
||||
path: field.subType.nested.path,
|
||||
query: query.query || query,
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export { migrateFilter } from './migrate_filter';
|
||||
export { buildEsQuery, EsQueryConfig } from './build_es_query';
|
||||
export { buildQueryFromFilters } from './from_filters';
|
||||
export { luceneStringToDsl } from './lucene_string_to_dsl';
|
||||
|
|
|
@ -12,6 +12,16 @@ import { PhraseFilter, MatchAllFilter } from '../filters';
|
|||
|
||||
describe('migrateFilter', function () {
|
||||
const oldMatchPhraseFilter = {
|
||||
match: {
|
||||
fieldFoo: {
|
||||
query: 'foobar',
|
||||
type: 'phrase',
|
||||
},
|
||||
},
|
||||
meta: {},
|
||||
} as unknown as DeprecatedMatchPhraseFilter;
|
||||
|
||||
const oldMatchPhraseFilter2 = {
|
||||
query: {
|
||||
match: {
|
||||
fieldFoo: {
|
||||
|
@ -36,8 +46,10 @@ describe('migrateFilter', function () {
|
|||
|
||||
it('should migrate match filters of type phrase', function () {
|
||||
const migratedFilter = migrateFilter(oldMatchPhraseFilter, undefined);
|
||||
|
||||
expect(migratedFilter).toEqual(newMatchPhraseFilter);
|
||||
|
||||
const migratedFilter2 = migrateFilter(oldMatchPhraseFilter2, undefined);
|
||||
expect(migratedFilter2).toEqual(newMatchPhraseFilter);
|
||||
});
|
||||
|
||||
it('should not modify the original filter', function () {
|
||||
|
@ -50,7 +62,7 @@ describe('migrateFilter', function () {
|
|||
|
||||
it('should return the original filter if no migration is necessary', function () {
|
||||
const originalFilter = {
|
||||
match_all: {},
|
||||
query: { match_all: {} },
|
||||
} as MatchAllFilter;
|
||||
const migratedFilter = migrateFilter(originalFilter, undefined);
|
||||
|
||||
|
|
|
@ -13,26 +13,31 @@ import { IndexPatternBase } from './types';
|
|||
|
||||
/** @internal */
|
||||
export interface DeprecatedMatchPhraseFilter extends Filter {
|
||||
query: {
|
||||
match: {
|
||||
[field: string]: {
|
||||
query: any;
|
||||
type: 'phrase';
|
||||
};
|
||||
match: {
|
||||
[field: string]: {
|
||||
query: any;
|
||||
type: 'phrase';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
function isDeprecatedMatchPhraseFilter(filter: Filter): filter is DeprecatedMatchPhraseFilter {
|
||||
const fieldName = Object.keys(filter.query?.match ?? {})[0];
|
||||
return Boolean(fieldName && get(filter, ['query', 'match', fieldName, 'type']) === 'phrase');
|
||||
// @ts-ignore
|
||||
const fieldName = Object.keys((filter.match || filter.query?.match) ?? {})[0];
|
||||
return Boolean(
|
||||
fieldName &&
|
||||
(get(filter, ['query', 'match', fieldName, 'type']) === 'phrase' ||
|
||||
get(filter, ['match', fieldName, 'type']) === 'phrase')
|
||||
);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function migrateFilter(filter: Filter, indexPattern?: IndexPatternBase) {
|
||||
if (isDeprecatedMatchPhraseFilter(filter)) {
|
||||
const fieldName = Object.keys(filter.query.match)[0];
|
||||
const params: Record<string, any> = get(filter, ['query', 'match', fieldName]);
|
||||
// @ts-ignore
|
||||
const match = filter.match || filter.query.match;
|
||||
const fieldName = Object.keys(match)[0];
|
||||
const params: Record<string, any> = get(match, [fieldName]);
|
||||
let query = params.query;
|
||||
if (indexPattern) {
|
||||
const field = indexPattern.fields.find((f) => f.name === fieldName);
|
||||
|
@ -42,7 +47,8 @@ export function migrateFilter(filter: Filter, indexPattern?: IndexPatternBase) {
|
|||
}
|
||||
}
|
||||
return {
|
||||
...filter,
|
||||
meta: filter.meta,
|
||||
$state: filter.$state,
|
||||
query: {
|
||||
match_phrase: {
|
||||
[fieldName]: omit(
|
||||
|
@ -57,5 +63,44 @@ export function migrateFilter(filter: Filter, indexPattern?: IndexPatternBase) {
|
|||
};
|
||||
}
|
||||
|
||||
if (!filter.query) {
|
||||
filter.query = {};
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
if (filter.exists) {
|
||||
// @ts-ignore
|
||||
filter.query.exists = filter.exists;
|
||||
// @ts-ignore
|
||||
delete filter.exists;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
if (filter.range) {
|
||||
// @ts-ignore
|
||||
filter.query.range = filter.range;
|
||||
// @ts-ignore
|
||||
delete filter.range;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
if (filter.match_all) {
|
||||
// @ts-ignore
|
||||
filter.query.match_all = filter.match_all;
|
||||
// @ts-ignore
|
||||
delete filter.match_all;
|
||||
}
|
||||
|
||||
// move all other keys under query
|
||||
Object.keys(filter).forEach((key) => {
|
||||
if (key === 'meta' || key === 'query' || key === '$state') {
|
||||
return;
|
||||
}
|
||||
// @ts-ignore
|
||||
filter.query[key] = filter[key];
|
||||
// @ts-ignore
|
||||
delete filter[key];
|
||||
});
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
|
|
@ -13,8 +13,10 @@ import type { Filter, FilterMeta } from './types';
|
|||
/** @public */
|
||||
export type ExistsFilter = Filter & {
|
||||
meta: FilterMeta;
|
||||
exists?: {
|
||||
field: string;
|
||||
query: {
|
||||
exists?: {
|
||||
field: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -24,13 +26,14 @@ export type ExistsFilter = Filter & {
|
|||
*
|
||||
* @public
|
||||
*/
|
||||
export const isExistsFilter = (filter: Filter): filter is ExistsFilter => has(filter, 'exists');
|
||||
export const isExistsFilter = (filter: Filter): filter is ExistsFilter =>
|
||||
has(filter, 'query.exists');
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const getExistsFilterField = (filter: ExistsFilter) => {
|
||||
return filter.exists && filter.exists.field;
|
||||
return filter.query.exists && filter.query.exists.field;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -46,8 +49,10 @@ export const buildExistsFilter = (field: IndexPatternFieldBase, indexPattern: In
|
|||
meta: {
|
||||
index: indexPattern.id,
|
||||
},
|
||||
exists: {
|
||||
field: field.name,
|
||||
query: {
|
||||
exists: {
|
||||
field: field.name,
|
||||
},
|
||||
},
|
||||
} as ExistsFilter;
|
||||
};
|
||||
|
|
|
@ -28,10 +28,8 @@ describe('getFilterField', function () {
|
|||
it('should return undefined for filters that do not target a specific field', () => {
|
||||
const filter = buildQueryFilter(
|
||||
{
|
||||
query: {
|
||||
query_string: {
|
||||
query: 'response:200 and extension:jpg',
|
||||
},
|
||||
query_string: {
|
||||
query: 'response:200 and extension:jpg',
|
||||
},
|
||||
},
|
||||
indexPattern.id!,
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
*/
|
||||
|
||||
import { getExistsFilterField, isExistsFilter } from './exists_filter';
|
||||
import { getMissingFilterField, isMissingFilter } from './missing_filter';
|
||||
import { getPhrasesFilterField, isPhrasesFilter } from './phrases_filter';
|
||||
import { getPhraseFilterField, isPhraseFilter } from './phrase_filter';
|
||||
import { getRangeFilterField, isRangeFilter } from './range_filter';
|
||||
|
@ -27,9 +26,6 @@ export const getFilterField = (filter: Filter) => {
|
|||
if (isRangeFilter(filter)) {
|
||||
return getRangeFilterField(filter);
|
||||
}
|
||||
if (isMissingFilter(filter)) {
|
||||
return getMissingFilterField(filter);
|
||||
}
|
||||
|
||||
return;
|
||||
};
|
||||
|
|
|
@ -14,7 +14,6 @@ export * from './exists_filter';
|
|||
export * from './get_filter_field';
|
||||
export * from './get_filter_params';
|
||||
export * from './match_all_filter';
|
||||
export * from './missing_filter';
|
||||
export * from './phrase_filter';
|
||||
export * from './phrases_filter';
|
||||
export * from './query_string_filter';
|
||||
|
|
|
@ -17,7 +17,9 @@ export interface MatchAllFilterMeta extends FilterMeta {
|
|||
|
||||
export type MatchAllFilter = Filter & {
|
||||
meta: MatchAllFilterMeta;
|
||||
match_all: estypes.QueryDslMatchAllQuery;
|
||||
query: {
|
||||
match_all: estypes.QueryDslMatchAllQuery;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -27,4 +29,4 @@ export type MatchAllFilter = Filter & {
|
|||
* @public
|
||||
*/
|
||||
export const isMatchAllFilter = (filter: Filter): filter is MatchAllFilter =>
|
||||
has(filter, 'match_all');
|
||||
has(filter, 'query.match_all');
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { getMissingFilterField } from './missing_filter';
|
||||
|
||||
describe('missing filter', function () {
|
||||
describe('getMissingFilterField', function () {
|
||||
it('should return the name of the field an missing query is targeting', () => {
|
||||
const filter = {
|
||||
missing: {
|
||||
field: 'extension',
|
||||
},
|
||||
meta: {
|
||||
disabled: false,
|
||||
negate: false,
|
||||
alias: null,
|
||||
},
|
||||
};
|
||||
const result = getMissingFilterField(filter);
|
||||
expect(result).toBe('extension');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { has } from 'lodash';
|
||||
import type { Filter, FilterMeta } from './types';
|
||||
|
||||
export type MissingFilterMeta = FilterMeta;
|
||||
|
||||
export type MissingFilter = Filter & {
|
||||
meta: MissingFilterMeta;
|
||||
missing: {
|
||||
field: string;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @param filter
|
||||
* @returns `true` if a filter is an `MissingFilter`
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const isMissingFilter = (filter: Filter): filter is MissingFilter => has(filter, 'missing');
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const getMissingFilterField = (filter: MissingFilter) => {
|
||||
return filter.missing && filter.missing.field;
|
||||
};
|
|
@ -83,13 +83,15 @@ describe('Phrase filter builder', () => {
|
|||
index: 'id',
|
||||
field: 'script number',
|
||||
},
|
||||
script: {
|
||||
query: {
|
||||
script: {
|
||||
lang: 'expression',
|
||||
params: {
|
||||
value: 5,
|
||||
script: {
|
||||
lang: 'expression',
|
||||
params: {
|
||||
value: 5,
|
||||
},
|
||||
source: '(1234) == value',
|
||||
},
|
||||
source: '(1234) == value',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -103,13 +105,15 @@ describe('Phrase filter builder', () => {
|
|||
index: 'id',
|
||||
field: 'script number',
|
||||
},
|
||||
script: {
|
||||
query: {
|
||||
script: {
|
||||
lang: 'expression',
|
||||
params: {
|
||||
value: 5,
|
||||
script: {
|
||||
lang: 'expression',
|
||||
params: {
|
||||
value: 5,
|
||||
},
|
||||
source: '(1234) == value',
|
||||
},
|
||||
source: '(1234) == value',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -100,7 +100,7 @@ export const buildPhraseFilter = (
|
|||
if (field.scripted) {
|
||||
return {
|
||||
meta: { index: indexPattern.id, field: field.name } as PhraseFilterMeta,
|
||||
script: getPhraseScript(field, value),
|
||||
query: { script: getPhraseScript(field, value) },
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
|
|
|
@ -14,13 +14,15 @@ describe('Query string filter builder', () => {
|
|||
});
|
||||
|
||||
it('should return a query filter when passed a standard field', () => {
|
||||
expect(buildQueryFilter({ foo: 'bar' }, 'index', '')).toEqual({
|
||||
expect(buildQueryFilter({ query_string: { query: 'bar' } }, 'index', '')).toEqual({
|
||||
meta: {
|
||||
alias: '',
|
||||
index: 'index',
|
||||
},
|
||||
query: {
|
||||
foo: 'bar',
|
||||
query_string: {
|
||||
query: 'bar',
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
|
|
@ -38,10 +38,12 @@ describe('Range filter builder', () => {
|
|||
index: 'id',
|
||||
params: {},
|
||||
},
|
||||
range: {
|
||||
bytes: {
|
||||
gte: 1,
|
||||
lte: 3,
|
||||
query: {
|
||||
range: {
|
||||
bytes: {
|
||||
gte: 1,
|
||||
lte: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -56,14 +58,16 @@ describe('Range filter builder', () => {
|
|||
index: 'id',
|
||||
params: {},
|
||||
},
|
||||
script: {
|
||||
query: {
|
||||
script: {
|
||||
lang: 'expression',
|
||||
source: '(' + field!.script + ')>=gte && (' + field!.script + ')<=lte',
|
||||
params: {
|
||||
value: '>=1 <=3',
|
||||
gte: 1,
|
||||
lte: 3,
|
||||
script: {
|
||||
lang: 'expression',
|
||||
source: '(' + field!.script + ')>=gte && (' + field!.script + ')<=lte',
|
||||
params: {
|
||||
value: '>=1 <=3',
|
||||
gte: 1,
|
||||
lte: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -79,14 +83,16 @@ describe('Range filter builder', () => {
|
|||
index: 'id',
|
||||
params: {},
|
||||
},
|
||||
script: {
|
||||
query: {
|
||||
script: {
|
||||
lang: 'expression',
|
||||
source: '(' + field!.script + ')>=gte && (' + field!.script + ')<=lte',
|
||||
params: {
|
||||
value: '>=1 <=3',
|
||||
gte: 1,
|
||||
lte: 3,
|
||||
script: {
|
||||
lang: 'expression',
|
||||
source: '(' + field!.script + ')>=gte && (' + field!.script + ')<=lte',
|
||||
params: {
|
||||
value: '>=1 <=3',
|
||||
gte: 1,
|
||||
lte: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -106,7 +112,7 @@ describe('Range filter builder', () => {
|
|||
{ gte: 1, lte: 3 },
|
||||
indexPattern
|
||||
) as ScriptedRangeFilter;
|
||||
expect(rangeFilter.script.script.source).toBe(expected);
|
||||
expect(rangeFilter.query.script.script.source).toBe(expected);
|
||||
});
|
||||
|
||||
it('should throw an error when gte and gt, or lte and lt are both passed', () => {
|
||||
|
@ -130,7 +136,7 @@ describe('Range filter builder', () => {
|
|||
};
|
||||
|
||||
const filter = buildRangeFilter(field!, params, indexPattern) as ScriptedRangeFilter;
|
||||
const script = filter.script!.script;
|
||||
const script = filter.query.script!.script;
|
||||
|
||||
expect(script.source).toBe('(' + field!.script + ')' + operator + key);
|
||||
expect(script.params?.[key]).toBe(5);
|
||||
|
@ -153,21 +159,21 @@ describe('Range filter builder', () => {
|
|||
|
||||
describe('returned filter', () => {
|
||||
it('is a script filter', () => {
|
||||
expect(filter).toHaveProperty('script');
|
||||
expect(filter.query).toHaveProperty('script');
|
||||
});
|
||||
|
||||
it('contain a param for the finite side', () => {
|
||||
expect(filter.script!.script.params).toHaveProperty('gte', 0);
|
||||
expect(filter.query.script!.script.params).toHaveProperty('gte', 0);
|
||||
});
|
||||
|
||||
it('does not contain a param for the infinite side', () => {
|
||||
expect(filter.script!.script.params).not.toHaveProperty('lt');
|
||||
expect(filter.query.script!.script.params).not.toHaveProperty('lt');
|
||||
});
|
||||
|
||||
it('does not contain a script condition for the infinite side', () => {
|
||||
const script = field!.script;
|
||||
|
||||
expect(filter.script!.script.source).toEqual(`(${script})>=gte`);
|
||||
expect(filter.query.script!.script.source).toEqual(`(${script})>=gte`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -187,12 +193,12 @@ describe('Range filter builder', () => {
|
|||
|
||||
describe('returned filter', () => {
|
||||
it('is a match_all filter', () => {
|
||||
expect(filter).not.toHaveProperty('script');
|
||||
expect(filter).toHaveProperty('match_all');
|
||||
expect(filter.query).not.toHaveProperty('script');
|
||||
expect(filter.query).toHaveProperty('match_all');
|
||||
});
|
||||
|
||||
it('does not contain params', () => {
|
||||
expect(filter).not.toHaveProperty('params');
|
||||
expect(filter.query).not.toHaveProperty('params');
|
||||
});
|
||||
|
||||
it('meta field is set to field name', () => {
|
||||
|
|
|
@ -60,14 +60,18 @@ export type RangeFilterMeta = FilterMeta & {
|
|||
|
||||
export type ScriptedRangeFilter = Filter & {
|
||||
meta: RangeFilterMeta;
|
||||
script: {
|
||||
script: estypes.InlineScript;
|
||||
query: {
|
||||
script: {
|
||||
script: estypes.InlineScript;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
export type MatchAllRangeFilter = Filter & {
|
||||
meta: RangeFilterMeta;
|
||||
match_all: estypes.QueryDslQueryContainer['match_all'];
|
||||
query: {
|
||||
match_all: estypes.QueryDslQueryContainer['match_all'];
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -75,7 +79,9 @@ export type MatchAllRangeFilter = Filter & {
|
|||
*/
|
||||
export type RangeFilter = Filter & {
|
||||
meta: RangeFilterMeta;
|
||||
range: { [key: string]: RangeFilterParams };
|
||||
query: {
|
||||
range: { [key: string]: RangeFilterParams };
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -84,7 +90,7 @@ export type RangeFilter = Filter & {
|
|||
*
|
||||
* @public
|
||||
*/
|
||||
export const isRangeFilter = (filter?: Filter): filter is RangeFilter => has(filter, 'range');
|
||||
export const isRangeFilter = (filter?: Filter): filter is RangeFilter => has(filter, 'query.range');
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -94,7 +100,7 @@ export const isRangeFilter = (filter?: Filter): filter is RangeFilter => has(fil
|
|||
* @public
|
||||
*/
|
||||
export const isScriptedRangeFilter = (filter: Filter): filter is ScriptedRangeFilter => {
|
||||
const params: RangeFilterParams = get(filter, 'script.script.params', {});
|
||||
const params: RangeFilterParams = get(filter, 'query.script.script.params', {});
|
||||
|
||||
return hasRangeKeys(params);
|
||||
};
|
||||
|
@ -103,7 +109,7 @@ export const isScriptedRangeFilter = (filter: Filter): filter is ScriptedRangeFi
|
|||
* @internal
|
||||
*/
|
||||
export const getRangeFilterField = (filter: RangeFilter) => {
|
||||
return filter.range && Object.keys(filter.range)[0];
|
||||
return filter.query.range && Object.keys(filter.query.range)[0];
|
||||
};
|
||||
|
||||
const formatValue = (params: any[]) =>
|
||||
|
@ -154,14 +160,14 @@ export const buildRangeFilter = (
|
|||
};
|
||||
|
||||
if (totalInfinite === OPERANDS_IN_RANGE) {
|
||||
return { meta, match_all: {} } as MatchAllRangeFilter;
|
||||
return { meta, query: { match_all: {} } } as MatchAllRangeFilter;
|
||||
} else if (field.scripted) {
|
||||
const scr = getRangeScript(field, params);
|
||||
// TODO: type mismatch enforced
|
||||
scr.script.params.value = formatValue(scr.script.params as any);
|
||||
return { meta, script: scr } as ScriptedRangeFilter;
|
||||
return { meta, query: { script: scr } } as ScriptedRangeFilter;
|
||||
} else {
|
||||
return { meta, range: { [field.name]: params } } as RangeFilter;
|
||||
return { meta, query: { range: { [field.name]: params } } } as RangeFilter;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ import { PhrasesFilter } from './phrases_filter';
|
|||
import { PhraseFilter } from './phrase_filter';
|
||||
import { RangeFilter } from './range_filter';
|
||||
import { MatchAllFilter } from './match_all_filter';
|
||||
import { MissingFilter } from './missing_filter';
|
||||
|
||||
/**
|
||||
* A common type for filters supported by this package
|
||||
|
@ -22,8 +21,7 @@ export type FieldFilter =
|
|||
| PhraseFilter
|
||||
| PhrasesFilter
|
||||
| RangeFilter
|
||||
| MatchAllFilter
|
||||
| MissingFilter;
|
||||
| MatchAllFilter;
|
||||
|
||||
/**
|
||||
* An enum of all types of filters supported by this package
|
||||
|
@ -35,7 +33,6 @@ export enum FILTERS {
|
|||
PHRASE = 'phrase',
|
||||
EXISTS = 'exists',
|
||||
MATCH_ALL = 'match_all',
|
||||
MISSING = 'missing',
|
||||
QUERY_STRING = 'query_string',
|
||||
RANGE = 'range',
|
||||
RANGE_FROM_VALUE = 'range_from_value',
|
||||
|
@ -74,8 +71,6 @@ export type Filter = {
|
|||
store: FilterStateStore;
|
||||
};
|
||||
meta: FilterMeta;
|
||||
|
||||
// TODO: research me! This is being extracted into the top level by translateToQuery. Maybe we can simplify.
|
||||
query?: Record<string, any>;
|
||||
};
|
||||
|
||||
|
|
|
@ -12,37 +12,21 @@ import { buildEmptyFilter, buildQueryFilter, FilterStateStore } from '..';
|
|||
describe('filter manager utilities', () => {
|
||||
describe('compare filters', () => {
|
||||
test('should compare filters', () => {
|
||||
const f1 = buildQueryFilter(
|
||||
{ _type: { match: { query: 'apache', type: 'phrase' } } },
|
||||
'index',
|
||||
''
|
||||
);
|
||||
const f1 = buildQueryFilter({ query_string: { query: 'apache' } }, 'index', '');
|
||||
const f2 = buildEmptyFilter(true);
|
||||
|
||||
expect(compareFilters(f1, f2)).toBeFalsy();
|
||||
});
|
||||
|
||||
test('should compare duplicates', () => {
|
||||
const f1 = buildQueryFilter(
|
||||
{ _type: { match: { query: 'apache', type: 'phrase' } } },
|
||||
'index',
|
||||
''
|
||||
);
|
||||
const f2 = buildQueryFilter(
|
||||
{ _type: { match: { query: 'apache', type: 'phrase' } } },
|
||||
'index',
|
||||
''
|
||||
);
|
||||
const f1 = buildQueryFilter({ query_string: { query: 'apache' } }, 'index', '');
|
||||
const f2 = buildQueryFilter({ query_string: { query: 'apache' } }, 'index', '');
|
||||
|
||||
expect(compareFilters(f1, f2)).toBeTruthy();
|
||||
});
|
||||
|
||||
test('should compare filters, where one filter is null', () => {
|
||||
const f1 = buildQueryFilter(
|
||||
{ _type: { match: { query: 'apache', type: 'phrase' } } },
|
||||
'index',
|
||||
''
|
||||
);
|
||||
const f1 = buildQueryFilter({ query_string: { query: 'apache' } }, 'index', '');
|
||||
const f2 = null;
|
||||
expect(compareFilters(f1, f2 as any)).toBeFalsy();
|
||||
});
|
||||
|
@ -54,16 +38,8 @@ describe('filter manager utilities', () => {
|
|||
});
|
||||
|
||||
test('should compare duplicates, ignoring meta attributes', () => {
|
||||
const f1 = buildQueryFilter(
|
||||
{ _type: { match: { query: 'apache', type: 'phrase' } } },
|
||||
'index1',
|
||||
''
|
||||
);
|
||||
const f2 = buildQueryFilter(
|
||||
{ _type: { match: { query: 'apache', type: 'phrase' } } },
|
||||
'index2',
|
||||
''
|
||||
);
|
||||
const f1 = buildQueryFilter({ query_string: { query: 'apache' } }, 'index1', '');
|
||||
const f2 = buildQueryFilter({ query_string: { query: 'apache' } }, 'index2', '');
|
||||
|
||||
expect(compareFilters(f1, f2)).toBeTruthy();
|
||||
});
|
||||
|
@ -71,75 +47,43 @@ describe('filter manager utilities', () => {
|
|||
test('should compare duplicates, ignoring $state attributes', () => {
|
||||
const f1 = {
|
||||
$state: { store: FilterStateStore.APP_STATE },
|
||||
...buildQueryFilter({ _type: { match: { query: 'apache', type: 'phrase' } } }, 'index', ''),
|
||||
...buildQueryFilter({ query_string: { query: 'apache' } }, 'index', ''),
|
||||
};
|
||||
const f2 = {
|
||||
$state: { store: FilterStateStore.GLOBAL_STATE },
|
||||
...buildQueryFilter({ _type: { match: { query: 'apache', type: 'phrase' } } }, 'index', ''),
|
||||
...buildQueryFilter({ query_string: { query: 'apache' } }, 'index', ''),
|
||||
};
|
||||
|
||||
expect(compareFilters(f1, f2)).toBeTruthy();
|
||||
});
|
||||
|
||||
test('should compare filters array to non array', () => {
|
||||
const f1 = buildQueryFilter(
|
||||
{ _type: { match: { query: 'apache', type: 'phrase' } } },
|
||||
'index',
|
||||
''
|
||||
);
|
||||
const f1 = buildQueryFilter({ query_string: { query: 'apache' } }, 'index', '');
|
||||
|
||||
const f2 = buildQueryFilter(
|
||||
{ _type: { match: { query: 'mochi', type: 'phrase' } } },
|
||||
'index',
|
||||
''
|
||||
);
|
||||
const f2 = buildQueryFilter({ query_string: { query: 'apache' } }, 'index', '');
|
||||
|
||||
expect(compareFilters([f1, f2], f1)).toBeFalsy();
|
||||
});
|
||||
|
||||
test('should compare filters array to partial array', () => {
|
||||
const f1 = buildQueryFilter(
|
||||
{ _type: { match: { query: 'apache', type: 'phrase' } } },
|
||||
'index',
|
||||
''
|
||||
);
|
||||
const f1 = buildQueryFilter({ query_string: { query: 'apache' } }, 'index', '');
|
||||
|
||||
const f2 = buildQueryFilter(
|
||||
{ _type: { match: { query: 'mochi', type: 'phrase' } } },
|
||||
'index',
|
||||
''
|
||||
);
|
||||
const f2 = buildQueryFilter({ query_string: { query: 'apache' } }, 'index', '');
|
||||
|
||||
expect(compareFilters([f1, f2], [f1])).toBeFalsy();
|
||||
});
|
||||
|
||||
test('should compare filters array to exact array', () => {
|
||||
const f1 = buildQueryFilter(
|
||||
{ _type: { match: { query: 'apache', type: 'phrase' } } },
|
||||
'index',
|
||||
''
|
||||
);
|
||||
const f1 = buildQueryFilter({ query_string: { query: 'apache' } }, 'index', '');
|
||||
|
||||
const f2 = buildQueryFilter(
|
||||
{ _type: { match: { query: 'mochi', type: 'phrase' } } },
|
||||
'index',
|
||||
''
|
||||
);
|
||||
const f2 = buildQueryFilter({ query_string: { query: 'apache' } }, 'index', '');
|
||||
|
||||
expect(compareFilters([f1, f2], [f1, f2])).toBeTruthy();
|
||||
});
|
||||
|
||||
test('should compare array of duplicates, ignoring meta attributes', () => {
|
||||
const f1 = buildQueryFilter(
|
||||
{ _type: { match: { query: 'apache', type: 'phrase' } } },
|
||||
'index1',
|
||||
''
|
||||
);
|
||||
const f2 = buildQueryFilter(
|
||||
{ _type: { match: { query: 'apache', type: 'phrase' } } },
|
||||
'index2',
|
||||
''
|
||||
);
|
||||
const f1 = buildQueryFilter({ query_string: { query: 'apache' } }, 'index1', '');
|
||||
const f2 = buildQueryFilter({ query_string: { query: 'apache' } }, 'index2', '');
|
||||
|
||||
expect(compareFilters([f1], [f2])).toBeTruthy();
|
||||
});
|
||||
|
@ -147,11 +91,11 @@ describe('filter manager utilities', () => {
|
|||
test('should compare array of duplicates, ignoring $state attributes', () => {
|
||||
const f1 = {
|
||||
$state: { store: FilterStateStore.APP_STATE },
|
||||
...buildQueryFilter({ _type: { match: { query: 'apache', type: 'phrase' } } }, 'index', ''),
|
||||
...buildQueryFilter({ query_string: { query: 'apache' } }, 'index', ''),
|
||||
};
|
||||
const f2 = {
|
||||
$state: { store: FilterStateStore.GLOBAL_STATE },
|
||||
...buildQueryFilter({ _type: { match: { query: 'apache', type: 'phrase' } } }, 'index', ''),
|
||||
...buildQueryFilter({ query_string: { query: 'apache' } }, 'index', ''),
|
||||
};
|
||||
|
||||
expect(compareFilters([f1], [f2])).toBeTruthy();
|
||||
|
@ -160,11 +104,11 @@ describe('filter manager utilities', () => {
|
|||
test('should compare duplicates with COMPARE_ALL_OPTIONS should check store', () => {
|
||||
const f1 = {
|
||||
$state: { store: FilterStateStore.APP_STATE },
|
||||
...buildQueryFilter({ _type: { match: { query: 'apache', type: 'phrase' } } }, 'index', ''),
|
||||
...buildQueryFilter({ query_string: { query: 'apache' } }, 'index', ''),
|
||||
};
|
||||
const f2 = {
|
||||
$state: { store: FilterStateStore.GLOBAL_STATE },
|
||||
...buildQueryFilter({ _type: { match: { query: 'apache', type: 'phrase' } } }, 'index', ''),
|
||||
...buildQueryFilter({ query_string: { query: 'apache' } }, 'index', ''),
|
||||
};
|
||||
|
||||
expect(compareFilters([f1], [f2], COMPARE_ALL_OPTIONS)).toBeFalsy();
|
||||
|
@ -173,11 +117,11 @@ describe('filter manager utilities', () => {
|
|||
test('should compare duplicates with COMPARE_ALL_OPTIONS should not check key and value ', () => {
|
||||
const f1 = {
|
||||
$state: { store: FilterStateStore.GLOBAL_STATE },
|
||||
...buildQueryFilter({ _type: { match: { query: 'apache', type: 'phrase' } } }, 'index', ''),
|
||||
...buildQueryFilter({ query_string: { query: 'apache' } }, 'index', ''),
|
||||
};
|
||||
const f2 = {
|
||||
$state: { store: FilterStateStore.GLOBAL_STATE },
|
||||
...buildQueryFilter({ _type: { match: { query: 'apache', type: 'phrase' } } }, 'index', ''),
|
||||
...buildQueryFilter({ query_string: { query: 'apache' } }, 'index', ''),
|
||||
};
|
||||
|
||||
f2.meta.key = 'wassup';
|
||||
|
@ -189,11 +133,11 @@ describe('filter manager utilities', () => {
|
|||
test('should compare alias with alias true', () => {
|
||||
const f1 = {
|
||||
$state: { store: FilterStateStore.GLOBAL_STATE },
|
||||
...buildQueryFilter({ _type: { match: { query: 'apache', type: 'phrase' } } }, 'index', ''),
|
||||
...buildQueryFilter({ query_string: { query: 'apache' } }, 'index', ''),
|
||||
};
|
||||
const f2 = {
|
||||
$state: { store: FilterStateStore.GLOBAL_STATE },
|
||||
...buildQueryFilter({ _type: { match: { query: 'apache', type: 'phrase' } } }, 'index', ''),
|
||||
...buildQueryFilter({ query_string: { query: 'apache' } }, 'index', ''),
|
||||
};
|
||||
|
||||
f2.meta.alias = 'wassup';
|
||||
|
@ -205,11 +149,11 @@ describe('filter manager utilities', () => {
|
|||
test('should compare alias with COMPARE_ALL_OPTIONS', () => {
|
||||
const f1 = {
|
||||
$state: { store: FilterStateStore.GLOBAL_STATE },
|
||||
...buildQueryFilter({ _type: { match: { query: 'apache', type: 'phrase' } } }, 'index', ''),
|
||||
...buildQueryFilter({ query_string: { query: 'apache' } }, 'index', ''),
|
||||
};
|
||||
const f2 = {
|
||||
$state: { store: FilterStateStore.GLOBAL_STATE },
|
||||
...buildQueryFilter({ _type: { match: { query: 'apache', type: 'phrase' } } }, 'index', ''),
|
||||
...buildQueryFilter({ query_string: { query: 'apache' } }, 'index', ''),
|
||||
};
|
||||
|
||||
f2.meta.alias = 'wassup';
|
||||
|
@ -221,11 +165,11 @@ describe('filter manager utilities', () => {
|
|||
test('should compare index with index true', () => {
|
||||
const f1 = {
|
||||
$state: { store: FilterStateStore.GLOBAL_STATE },
|
||||
...buildQueryFilter({ _type: { match: { query: 'apache', type: 'phrase' } } }, 'index', ''),
|
||||
...buildQueryFilter({ query_string: { query: 'apache' } }, 'index', ''),
|
||||
};
|
||||
const f2 = {
|
||||
$state: { store: FilterStateStore.GLOBAL_STATE },
|
||||
...buildQueryFilter({ _type: { match: { query: 'apache', type: 'phrase' } } }, 'index', ''),
|
||||
...buildQueryFilter({ query_string: { query: 'apache' } }, 'index', ''),
|
||||
};
|
||||
|
||||
f2.meta.index = 'wassup';
|
||||
|
|
|
@ -28,7 +28,7 @@ describe('filter manager utilities', () => {
|
|||
indexPattern,
|
||||
''
|
||||
),
|
||||
buildQueryFilter({ match: { _term: { query: 'apache', type: 'phrase' } } }, 'index', ''),
|
||||
buildQueryFilter({ query_string: { query: 'apache' } }, 'index', ''),
|
||||
];
|
||||
const filters: Filter[] = [
|
||||
buildRangeFilter(
|
||||
|
@ -37,7 +37,7 @@ describe('filter manager utilities', () => {
|
|||
indexPattern,
|
||||
''
|
||||
),
|
||||
buildQueryFilter({ match: { _term: { query: 'apache', type: 'phrase' } } }, 'index', ''),
|
||||
buildQueryFilter({ query_string: { query: 'apache' } }, 'index', ''),
|
||||
];
|
||||
const results = dedupFilters(existing, filters);
|
||||
|
||||
|
@ -54,11 +54,7 @@ describe('filter manager utilities', () => {
|
|||
''
|
||||
),
|
||||
{
|
||||
...buildQueryFilter(
|
||||
{ match: { _term: { query: 'apache', type: 'phrase' } } },
|
||||
'index1',
|
||||
''
|
||||
),
|
||||
...buildQueryFilter({ query_string: { query: 'apache' } }, 'index1', ''),
|
||||
meta: { disabled: true, negate: false, alias: null },
|
||||
},
|
||||
];
|
||||
|
@ -69,7 +65,7 @@ describe('filter manager utilities', () => {
|
|||
indexPattern,
|
||||
''
|
||||
),
|
||||
buildQueryFilter({ match: { _term: { query: 'apache', type: 'phrase' } } }, 'index1', ''),
|
||||
buildQueryFilter({ query_string: { query: 'apache' } }, 'index1', ''),
|
||||
];
|
||||
const results = dedupFilters(existing, filters);
|
||||
|
||||
|
@ -86,11 +82,7 @@ describe('filter manager utilities', () => {
|
|||
''
|
||||
),
|
||||
{
|
||||
...buildQueryFilter(
|
||||
{ match: { _term: { query: 'apache', type: 'phrase' } } },
|
||||
'index',
|
||||
''
|
||||
),
|
||||
...buildQueryFilter({ query_string: { query: 'apache' } }, 'index', ''),
|
||||
$state: { store: FilterStateStore.APP_STATE },
|
||||
},
|
||||
];
|
||||
|
@ -102,11 +94,7 @@ describe('filter manager utilities', () => {
|
|||
''
|
||||
),
|
||||
{
|
||||
...buildQueryFilter(
|
||||
{ match: { _term: { query: 'apache', type: 'phrase' } } },
|
||||
'index',
|
||||
''
|
||||
),
|
||||
...buildQueryFilter({ query_string: { query: 'apache' } }, 'index', ''),
|
||||
$state: { store: FilterStateStore.GLOBAL_STATE },
|
||||
},
|
||||
];
|
||||
|
|
|
@ -13,8 +13,8 @@ describe('filter manager utilities', () => {
|
|||
describe('niqFilter', () => {
|
||||
test('should filter out dups', () => {
|
||||
const before: Filter[] = [
|
||||
buildQueryFilter({ _type: { match: { query: 'apache', type: 'phrase' } } }, 'index', ''),
|
||||
buildQueryFilter({ _type: { match: { query: 'apache', type: 'phrase' } } }, 'index', ''),
|
||||
buildQueryFilter({ query_string: { query: 'apache' } }, 'index', ''),
|
||||
buildQueryFilter({ query_string: { query: 'apache' } }, 'index', ''),
|
||||
];
|
||||
const results = uniqFilters(before);
|
||||
|
||||
|
@ -23,8 +23,8 @@ describe('filter manager utilities', () => {
|
|||
|
||||
test('should filter out duplicates, ignoring meta attributes', () => {
|
||||
const before: Filter[] = [
|
||||
buildQueryFilter({ _type: { match: { query: 'apache', type: 'phrase' } } }, 'index1', ''),
|
||||
buildQueryFilter({ _type: { match: { query: 'apache', type: 'phrase' } } }, 'index2', ''),
|
||||
buildQueryFilter({ query_string: { query: 'apache' } }, 'index1', ''),
|
||||
buildQueryFilter({ query_string: { query: 'apache' } }, 'index2', ''),
|
||||
];
|
||||
const results = uniqFilters(before);
|
||||
|
||||
|
@ -35,19 +35,11 @@ describe('filter manager utilities', () => {
|
|||
const before: Filter[] = [
|
||||
{
|
||||
$state: { store: FilterStateStore.APP_STATE },
|
||||
...buildQueryFilter(
|
||||
{ _type: { match: { query: 'apache', type: 'phrase' } } },
|
||||
'index',
|
||||
''
|
||||
),
|
||||
...buildQueryFilter({ query_string: { query: 'apache' } }, 'index', ''),
|
||||
},
|
||||
{
|
||||
$state: { store: FilterStateStore.GLOBAL_STATE },
|
||||
...buildQueryFilter(
|
||||
{ _type: { match: { query: 'apache', type: 'phrase' } } },
|
||||
'index',
|
||||
''
|
||||
),
|
||||
...buildQueryFilter({ query_string: { query: 'apache' } }, 'index', ''),
|
||||
},
|
||||
];
|
||||
const results = uniqFilters(before);
|
||||
|
|
|
@ -30,7 +30,6 @@ export {
|
|||
export {
|
||||
isExistsFilter,
|
||||
isMatchAllFilter,
|
||||
isMissingFilter,
|
||||
isPhraseFilter,
|
||||
isPhrasesFilter,
|
||||
isRangeFilter,
|
||||
|
@ -69,7 +68,6 @@ export {
|
|||
RangeFilterMeta,
|
||||
MatchAllFilter,
|
||||
CustomFilter,
|
||||
MissingFilter,
|
||||
RangeFilterParams,
|
||||
QueryStringFilter,
|
||||
} from './build_filters';
|
||||
|
|
|
@ -20,4 +20,5 @@ export const existsFilter: ExistsFilter = {
|
|||
$state: {
|
||||
store: FilterStateStore.APP_STATE,
|
||||
},
|
||||
query: {},
|
||||
};
|
||||
|
|
|
@ -25,5 +25,5 @@ export const rangeFilter: RangeFilter = {
|
|||
$state: {
|
||||
store: FilterStateStore.APP_STATE,
|
||||
},
|
||||
range: {},
|
||||
query: { range: {} },
|
||||
};
|
||||
|
|
|
@ -23,6 +23,7 @@ import {
|
|||
} from '@kbn/securitysolution-io-ts-list-types';
|
||||
import { Filter } from '@kbn/es-query';
|
||||
|
||||
import { QueryDslBoolQuery, QueryDslNestedQuery } from '@elastic/elasticsearch/api/types';
|
||||
import { hasLargeValueList } from '../has_large_value_list';
|
||||
|
||||
type NonListEntry = EntryMatch | EntryMatchAny | EntryNested | EntryExists;
|
||||
|
@ -39,21 +40,11 @@ export type ExceptionItemSansLargeValueLists =
|
|||
| CreateExceptionListItemNonLargeList;
|
||||
|
||||
export interface BooleanFilter {
|
||||
bool: {
|
||||
must?: unknown | unknown[];
|
||||
must_not?: unknown | unknown[];
|
||||
should?: unknown[];
|
||||
filter?: unknown | unknown[];
|
||||
minimum_should_match?: number;
|
||||
};
|
||||
bool: QueryDslBoolQuery;
|
||||
}
|
||||
|
||||
export interface NestedFilter {
|
||||
nested: {
|
||||
path: string;
|
||||
query: unknown | unknown[];
|
||||
score_mode: string;
|
||||
};
|
||||
nested: QueryDslNestedQuery;
|
||||
}
|
||||
|
||||
export const chunkExceptions = (
|
||||
|
@ -178,7 +169,7 @@ export const buildExceptionFilter = ({
|
|||
return undefined;
|
||||
} else if (exceptionsWithoutLargeValueLists.length <= chunkSize) {
|
||||
const clause = createOrClauses(exceptionsWithoutLargeValueLists);
|
||||
exceptionFilter.query!.bool.should = clause;
|
||||
exceptionFilter.query!.bool!.should = clause;
|
||||
return exceptionFilter;
|
||||
} else {
|
||||
const chunks = chunkExceptions(exceptionsWithoutLargeValueLists, chunkSize);
|
||||
|
|
|
@ -29,7 +29,6 @@ import {
|
|||
isFilters as oldIsFilters,
|
||||
isExistsFilter as oldIsExistsFilter,
|
||||
isMatchAllFilter as oldIsMatchAllFilter,
|
||||
isMissingFilter as oldIsMissingFilter,
|
||||
isPhraseFilter as oldIsPhraseFilter,
|
||||
isPhrasesFilter as oldIsPhrasesFilter,
|
||||
isRangeFilter as oldIsRangeFilter,
|
||||
|
@ -51,7 +50,6 @@ import {
|
|||
PhraseFilter as oldPhraseFilter,
|
||||
MatchAllFilter as oldMatchAllFilter,
|
||||
CustomFilter as oldCustomFilter,
|
||||
MissingFilter as oldMissingFilter,
|
||||
RangeFilter as oldRangeFilter,
|
||||
KueryNode as oldKueryNode,
|
||||
FilterMeta as oldFilterMeta,
|
||||
|
@ -172,12 +170,6 @@ const isExistsFilter = oldIsExistsFilter;
|
|||
*/
|
||||
const isMatchAllFilter = oldIsMatchAllFilter;
|
||||
|
||||
/**
|
||||
* @deprecated Import from the "@kbn/es-query" package directly instead.
|
||||
* @removeBy 8.1
|
||||
*/
|
||||
const isMissingFilter = oldIsMissingFilter;
|
||||
|
||||
/**
|
||||
* @deprecated Import from the "@kbn/es-query" package directly instead.
|
||||
* @removeBy 8.1
|
||||
|
@ -346,12 +338,6 @@ type MatchAllFilter = oldMatchAllFilter;
|
|||
*/
|
||||
type CustomFilter = oldCustomFilter;
|
||||
|
||||
/**
|
||||
* @deprecated Import from the "@kbn/es-query" package directly instead.
|
||||
* @removeBy 8.1
|
||||
*/
|
||||
type MissingFilter = oldMissingFilter;
|
||||
|
||||
/**
|
||||
* @deprecated Import from the "@kbn/es-query" package directly instead.
|
||||
* @removeBy 8.1
|
||||
|
@ -408,7 +394,6 @@ export {
|
|||
isFilters,
|
||||
isExistsFilter,
|
||||
isMatchAllFilter,
|
||||
isMissingFilter,
|
||||
isPhraseFilter,
|
||||
isPhrasesFilter,
|
||||
isRangeFilter,
|
||||
|
@ -437,7 +422,6 @@ export {
|
|||
PhraseFilter,
|
||||
MatchAllFilter,
|
||||
CustomFilter,
|
||||
MissingFilter,
|
||||
RangeFilter,
|
||||
KueryNode,
|
||||
FilterMeta,
|
||||
|
|
|
@ -20,4 +20,5 @@ export const existsFilter: ExistsFilter = {
|
|||
$state: {
|
||||
store: FilterStateStore.APP_STATE,
|
||||
},
|
||||
query: {},
|
||||
};
|
||||
|
|
|
@ -25,5 +25,5 @@ export const rangeFilter: RangeFilter = {
|
|||
$state: {
|
||||
store: FilterStateStore.APP_STATE,
|
||||
},
|
||||
range: {},
|
||||
query: { range: {} },
|
||||
};
|
||||
|
|
|
@ -35,7 +35,7 @@ describe('get_time', () => {
|
|||
} as unknown as IIndexPattern,
|
||||
{ from: 'now-60y', to: 'now' }
|
||||
) as RangeFilter;
|
||||
expect(filter.range.date).toEqual({
|
||||
expect(filter.query.range.date).toEqual({
|
||||
gte: '1940-02-01T00:00:00.000Z',
|
||||
lte: '2000-02-01T00:00:00.000Z',
|
||||
format: 'strict_date_optional_time',
|
||||
|
@ -73,7 +73,7 @@ describe('get_time', () => {
|
|||
{ from: 'now-60y', to: 'now' },
|
||||
{ fieldName: 'myCustomDate' }
|
||||
) as RangeFilter;
|
||||
expect(filter.range.myCustomDate).toEqual({
|
||||
expect(filter.query.range.myCustomDate).toEqual({
|
||||
gte: '1940-02-01T00:00:00.000Z',
|
||||
lte: '2000-02-01T00:00:00.000Z',
|
||||
format: 'strict_date_optional_time',
|
||||
|
@ -111,7 +111,7 @@ describe('get_time', () => {
|
|||
{ fieldName: 'myCustomDate' }
|
||||
) as RangeFilter;
|
||||
|
||||
expect(filter.range.myCustomDate).toEqual({
|
||||
expect(filter.query.range.myCustomDate).toEqual({
|
||||
gte: 'now-60y',
|
||||
lte: 'now',
|
||||
format: 'strict_date_optional_time',
|
||||
|
@ -150,7 +150,7 @@ describe('get_time', () => {
|
|||
{ fieldName: 'myCustomDate' }
|
||||
) as RangeFilter;
|
||||
|
||||
expect(filter.range.myCustomDate).toEqual({
|
||||
expect(filter.query.range.myCustomDate).toEqual({
|
||||
gte: '2020-09-01T08:30:00.000Z',
|
||||
lte: 'now',
|
||||
format: 'strict_date_optional_time',
|
||||
|
|
|
@ -406,8 +406,8 @@ export class AggConfigs {
|
|||
.map(([filter, field]) => ({
|
||||
range: {
|
||||
[field]: {
|
||||
gte: moment(filter?.range[field].gte).subtract(shift).toISOString(),
|
||||
lte: moment(filter?.range[field].lte).subtract(shift).toISOString(),
|
||||
gte: moment(filter?.query.range[field].gte).subtract(shift).toISOString(),
|
||||
lte: moment(filter?.query.range[field].lte).subtract(shift).toISOString(),
|
||||
},
|
||||
},
|
||||
})),
|
||||
|
|
|
@ -69,10 +69,10 @@ describe('AggConfig Filters', () => {
|
|||
test('creates a valid range filter', () => {
|
||||
init();
|
||||
|
||||
expect(filter).toHaveProperty('range');
|
||||
expect(filter.range).toHaveProperty(field.name);
|
||||
expect(filter.query).toHaveProperty('range');
|
||||
expect(filter.query.range).toHaveProperty(field.name);
|
||||
|
||||
const fieldParams = filter.range[field.name];
|
||||
const fieldParams = filter.query.range[field.name];
|
||||
expect(fieldParams).toHaveProperty('gte');
|
||||
expect(typeof fieldParams.gte).toBe('string');
|
||||
|
||||
|
@ -100,7 +100,7 @@ describe('AggConfig Filters', () => {
|
|||
init(option.val, duration);
|
||||
|
||||
const interval = agg.buckets.getInterval();
|
||||
const params = filter.range[field.name];
|
||||
const params = filter.query.range[field.name];
|
||||
|
||||
expect(params.gte).toBe(bucketStart.toISOString());
|
||||
expect(params.lt).toBe(bucketStart.clone().add(interval).toISOString());
|
||||
|
|
|
@ -57,12 +57,12 @@ describe('AggConfig Filters', () => {
|
|||
to: to.valueOf(),
|
||||
}) as RangeFilter;
|
||||
|
||||
expect(filter).toHaveProperty('range');
|
||||
expect(filter.query).toHaveProperty('range');
|
||||
expect(filter).toHaveProperty('meta');
|
||||
expect(filter.meta).toHaveProperty('index', '1234');
|
||||
expect(filter.range).toHaveProperty('@timestamp');
|
||||
expect(filter.range['@timestamp']).toHaveProperty('gte', moment(from).toISOString());
|
||||
expect(filter.range['@timestamp']).toHaveProperty('lt', moment(to).toISOString());
|
||||
expect(filter.query.range).toHaveProperty('@timestamp');
|
||||
expect(filter.query.range['@timestamp']).toHaveProperty('gte', moment(from).toISOString());
|
||||
expect(filter.query.range['@timestamp']).toHaveProperty('lt', moment(to).toISOString());
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -79,7 +79,7 @@ describe('AggConfig Filters', () => {
|
|||
}
|
||||
`);
|
||||
|
||||
expect(filter.query?.bool.must[0].query_string.query).toBe('type:nginx');
|
||||
expect((filter.query?.bool?.must as any)[0].query_string.query).toBe('type:nginx');
|
||||
expect(filter.meta).toHaveProperty('index', '1234');
|
||||
expect(filter.meta).toHaveProperty('alias', 'type:nginx');
|
||||
});
|
||||
|
|
|
@ -18,10 +18,10 @@ function validateFilter(filter: RangeFilter) {
|
|||
expect(mockGetFieldFormatsStart().deserialize).toHaveBeenCalledTimes(1);
|
||||
expect(filter).toHaveProperty('meta');
|
||||
expect(filter.meta).toHaveProperty('index', '1234');
|
||||
expect(filter).toHaveProperty('range');
|
||||
expect(filter.range).toHaveProperty('bytes');
|
||||
expect(filter.range.bytes).toHaveProperty('gte', 2048);
|
||||
expect(filter.range.bytes).toHaveProperty('lt', 3072);
|
||||
expect(filter.query).toHaveProperty('range');
|
||||
expect(filter.query.range).toHaveProperty('bytes');
|
||||
expect(filter.query.range.bytes).toHaveProperty('gte', 2048);
|
||||
expect(filter.query.range.bytes).toHaveProperty('lt', 3072);
|
||||
expect(filter.meta).toHaveProperty('formattedValue');
|
||||
}
|
||||
|
||||
|
|
|
@ -56,12 +56,12 @@ describe('AggConfig Filters', () => {
|
|||
to: '1.1.1.1',
|
||||
}) as RangeFilter;
|
||||
|
||||
expect(filter).toHaveProperty('range');
|
||||
expect(filter.query).toHaveProperty('range');
|
||||
expect(filter).toHaveProperty('meta');
|
||||
expect(filter.meta).toHaveProperty('index', '1234');
|
||||
expect(filter.range).toHaveProperty('ip');
|
||||
expect(filter.range.ip).toHaveProperty('gte', '0.0.0.0');
|
||||
expect(filter.range.ip).toHaveProperty('lte', '1.1.1.1');
|
||||
expect(filter.query.range).toHaveProperty('ip');
|
||||
expect(filter.query.range.ip).toHaveProperty('gte', '0.0.0.0');
|
||||
expect(filter.query.range.ip).toHaveProperty('lte', '1.1.1.1');
|
||||
});
|
||||
|
||||
test('should return a range filter for ip_range agg using a CIDR mask', () => {
|
||||
|
@ -84,12 +84,12 @@ describe('AggConfig Filters', () => {
|
|||
mask: '67.129.65.201/27',
|
||||
}) as RangeFilter;
|
||||
|
||||
expect(filter).toHaveProperty('range');
|
||||
expect(filter.query).toHaveProperty('range');
|
||||
expect(filter).toHaveProperty('meta');
|
||||
expect(filter.meta).toHaveProperty('index', '1234');
|
||||
expect(filter.range).toHaveProperty('ip');
|
||||
expect(filter.range.ip).toHaveProperty('gte', '67.129.65.192');
|
||||
expect(filter.range.ip).toHaveProperty('lte', '67.129.65.223');
|
||||
expect(filter.query.range).toHaveProperty('ip');
|
||||
expect(filter.query.range.ip).toHaveProperty('gte', '67.129.65.192');
|
||||
expect(filter.query.range.ip).toHaveProperty('lte', '67.129.65.223');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -63,13 +63,13 @@ describe('AggConfig Filters', () => {
|
|||
) as RangeFilter;
|
||||
|
||||
expect(mockGetFieldFormatsStart().deserialize).toHaveBeenCalledTimes(1);
|
||||
expect(filter).toHaveProperty('range');
|
||||
expect(filter.query).toHaveProperty('range');
|
||||
expect(filter).toHaveProperty('meta');
|
||||
expect(filter.meta).toHaveProperty('index', '1234');
|
||||
expect(filter.range).toHaveProperty('bytes');
|
||||
expect(filter.range.bytes).toHaveProperty('gte', 1024.0);
|
||||
expect(filter.range.bytes).toHaveProperty('lt', 2048.0);
|
||||
expect(filter.range.bytes).not.toHaveProperty('label');
|
||||
expect(filter.query.range).toHaveProperty('bytes');
|
||||
expect(filter.query.range.bytes).toHaveProperty('gte', 1024.0);
|
||||
expect(filter.query.range.bytes).toHaveProperty('lt', 2048.0);
|
||||
expect(filter.query.range.bytes).not.toHaveProperty('label');
|
||||
expect(filter.meta).toHaveProperty('formattedValue');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -49,7 +49,7 @@ describe('AggConfig Filters', () => {
|
|||
expect(filter).toHaveProperty('query');
|
||||
expect(filter.query).toHaveProperty('match_phrase');
|
||||
expect(filter.query?.match_phrase).toHaveProperty('field');
|
||||
expect(filter.query?.match_phrase.field).toBe('apache');
|
||||
expect(filter.query?.match_phrase?.field).toBe('apache');
|
||||
expect(filter).toHaveProperty('meta');
|
||||
expect(filter.meta).toHaveProperty('index', '1234');
|
||||
});
|
||||
|
@ -68,7 +68,7 @@ describe('AggConfig Filters', () => {
|
|||
expect(filterFalse).toHaveProperty('query');
|
||||
expect(filterFalse.query).toHaveProperty('match_phrase');
|
||||
expect(filterFalse.query?.match_phrase).toHaveProperty('field');
|
||||
expect(filterFalse.query?.match_phrase.field).toBeFalsy();
|
||||
expect(filterFalse.query?.match_phrase?.field).toBeFalsy();
|
||||
|
||||
const filterTrue = createFilterTerms(
|
||||
aggConfigs.aggs[0] as IBucketAggConfig,
|
||||
|
@ -79,7 +79,7 @@ describe('AggConfig Filters', () => {
|
|||
expect(filterTrue).toHaveProperty('query');
|
||||
expect(filterTrue.query).toHaveProperty('match_phrase');
|
||||
expect(filterTrue.query?.match_phrase).toHaveProperty('field');
|
||||
expect(filterTrue.query?.match_phrase.field).toBeTruthy();
|
||||
expect(filterTrue.query?.match_phrase?.field).toBeTruthy();
|
||||
});
|
||||
|
||||
test('should generate correct __missing__ filter', () => {
|
||||
|
@ -92,8 +92,8 @@ describe('AggConfig Filters', () => {
|
|||
{}
|
||||
) as ExistsFilter;
|
||||
|
||||
expect(filter).toHaveProperty('exists');
|
||||
expect(filter.exists).toHaveProperty('field', 'field');
|
||||
expect(filter.query).toHaveProperty('exists');
|
||||
expect(filter.query.exists).toHaveProperty('field', 'field');
|
||||
expect(filter).toHaveProperty('meta');
|
||||
expect(filter.meta).toHaveProperty('index', '1234');
|
||||
expect(filter.meta).toHaveProperty('negate', true);
|
||||
|
@ -111,8 +111,8 @@ describe('AggConfig Filters', () => {
|
|||
expect(filter).toHaveProperty('query');
|
||||
expect(filter.query).toHaveProperty('bool');
|
||||
expect(filter.query?.bool).toHaveProperty('should');
|
||||
expect(filter.query?.bool.should[0]).toHaveProperty('match_phrase');
|
||||
expect(filter.query?.bool.should[0].match_phrase).toHaveProperty('field', 'apache');
|
||||
expect((filter.query?.bool?.should as any)[0]).toHaveProperty('match_phrase');
|
||||
expect((filter.query?.bool!.should as any)[0].match_phrase).toHaveProperty('field', 'apache');
|
||||
expect(filter).toHaveProperty('meta');
|
||||
expect(filter.meta).toHaveProperty('index', '1234');
|
||||
expect(filter.meta).toHaveProperty('negate', true);
|
||||
|
|
|
@ -430,8 +430,8 @@ export function insertTimeShiftSplit(
|
|||
filters[key] = {
|
||||
range: {
|
||||
[timeField]: {
|
||||
gte: moment(timeFilter.range[timeField].gte).subtract(shift).toISOString(),
|
||||
lte: moment(timeFilter.range[timeField].lte).subtract(shift).toISOString(),
|
||||
gte: moment(timeFilter.query.range[timeField].gte).subtract(shift).toISOString(),
|
||||
lte: moment(timeFilter.query.range[timeField].lte).subtract(shift).toISOString(),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -93,7 +93,7 @@ describe('createFilter', () => {
|
|||
|
||||
if (filters) {
|
||||
expect(filters.length).toEqual(1);
|
||||
expect(filters[0].query!.match_phrase.bytes).toEqual('2048');
|
||||
expect(filters[0].query!.match_phrase!.bytes).toEqual('2048');
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -109,8 +109,8 @@ describe('createFilter', () => {
|
|||
const [rangeFilter] = filters;
|
||||
|
||||
if (isRangeFilter(rangeFilter)) {
|
||||
expect(rangeFilter.range.bytes.gte).toEqual(2048);
|
||||
expect(rangeFilter.range.bytes.lt).toEqual(2078);
|
||||
expect(rangeFilter.query.range.bytes.gte).toEqual(2048);
|
||||
expect(rangeFilter.query.range.bytes.lt).toEqual(2078);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -17,15 +17,17 @@ describe('interpreter/functions#existsFilter', () => {
|
|||
const actual = fn(null, { field: { spec: { name: 'test' } } }, createMockContext());
|
||||
expect(actual).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"exists": Object {
|
||||
"field": "test",
|
||||
},
|
||||
"meta": Object {
|
||||
"alias": null,
|
||||
"disabled": false,
|
||||
"index": undefined,
|
||||
"negate": false,
|
||||
},
|
||||
"query": Object {
|
||||
"exists": Object {
|
||||
"field": "test",
|
||||
},
|
||||
},
|
||||
"type": "kibana_filter",
|
||||
}
|
||||
`);
|
||||
|
|
|
@ -11,11 +11,11 @@ import { filtersToAst } from './filters_to_ast';
|
|||
describe('interpreter/functions#filtersToAst', () => {
|
||||
const normalFilter = {
|
||||
meta: { negate: false, alias: '', disabled: false },
|
||||
query: { test: 'something' },
|
||||
query: { query_string: { query: 'something' } },
|
||||
};
|
||||
const negatedFilter = {
|
||||
meta: { negate: true, alias: '', disabled: false },
|
||||
query: { test: 'something' },
|
||||
query: { query_string: { query: 'test' } },
|
||||
};
|
||||
|
||||
it('converts a list of filters to an expression AST node', () => {
|
||||
|
@ -28,7 +28,7 @@ describe('interpreter/functions#filtersToAst', () => {
|
|||
expect.objectContaining({
|
||||
disabled: [false],
|
||||
negate: [false],
|
||||
query: ['{"query":{"test":"something"}}'],
|
||||
query: ['{"query_string":{"query":"something"}}'],
|
||||
})
|
||||
);
|
||||
|
||||
|
@ -39,7 +39,7 @@ describe('interpreter/functions#filtersToAst', () => {
|
|||
expect.objectContaining({
|
||||
disabled: [false],
|
||||
negate: [true],
|
||||
query: ['{"query":{"test":"something"}}'],
|
||||
query: ['{"query_string":{"query":"test"}}'],
|
||||
})
|
||||
);
|
||||
});
|
||||
|
|
|
@ -12,12 +12,12 @@ import { ExpressionFunctionKibanaFilter } from './kibana_filter';
|
|||
|
||||
export const filtersToAst = (filters: Filter[] | Filter) => {
|
||||
return (Array.isArray(filters) ? filters : [filters]).map((filter) => {
|
||||
const { meta, $state, ...restOfFilter } = filter;
|
||||
const { meta, $state, query, ...restOfFilters } = filter;
|
||||
return buildExpression([
|
||||
buildExpressionFunction<ExpressionFunctionKibanaFilter>('kibanaFilter', {
|
||||
query: JSON.stringify(restOfFilter),
|
||||
negate: filter.meta.negate,
|
||||
disabled: filter.meta.disabled,
|
||||
query: JSON.stringify(query || restOfFilters),
|
||||
negate: meta.negate,
|
||||
disabled: meta.disabled,
|
||||
}),
|
||||
]).toAst();
|
||||
});
|
||||
|
|
|
@ -22,7 +22,9 @@ describe('interpreter/functions#kibanaFilter', () => {
|
|||
"disabled": false,
|
||||
"negate": false,
|
||||
},
|
||||
"name": "test",
|
||||
"query": Object {
|
||||
"name": "test",
|
||||
},
|
||||
"type": "kibana_filter",
|
||||
}
|
||||
`);
|
||||
|
|
|
@ -63,7 +63,7 @@ export const kibanaFilterFunction: ExpressionFunctionKibanaFilter = {
|
|||
alias: '',
|
||||
disabled: args.disabled || false,
|
||||
},
|
||||
...JSON.parse(args.query),
|
||||
query: JSON.parse(args.query),
|
||||
};
|
||||
},
|
||||
};
|
||||
|
|
|
@ -29,10 +29,12 @@ describe('interpreter/functions#rangeFilter', () => {
|
|||
"negate": false,
|
||||
"params": Object {},
|
||||
},
|
||||
"range": Object {
|
||||
"test": Object {
|
||||
"gte": 10,
|
||||
"lt": 20,
|
||||
"query": Object {
|
||||
"range": Object {
|
||||
"test": Object {
|
||||
"gte": 10,
|
||||
"lt": 20,
|
||||
},
|
||||
},
|
||||
},
|
||||
"type": "kibana_filter",
|
||||
|
|
|
@ -824,7 +824,7 @@ describe('SearchSource', () => {
|
|||
test('should serialize filters', () => {
|
||||
const filter = [
|
||||
{
|
||||
query: { q: 'query' },
|
||||
query: { query_string: { query: 'query' } },
|
||||
meta: {
|
||||
alias: 'alias',
|
||||
disabled: false,
|
||||
|
@ -842,7 +842,7 @@ describe('SearchSource', () => {
|
|||
searchSource.setField('index', indexPattern123);
|
||||
const filter = [
|
||||
{
|
||||
query: { q: 'query' },
|
||||
query: { query_string: { query: 'query' } },
|
||||
meta: {
|
||||
alias: 'alias',
|
||||
disabled: false,
|
||||
|
@ -885,7 +885,7 @@ describe('SearchSource', () => {
|
|||
describe('getSerializedFields', () => {
|
||||
const filter: Filter[] = [
|
||||
{
|
||||
query: { q: 'query' },
|
||||
query: { query_string: { query: 'query' } },
|
||||
meta: {
|
||||
alias: 'alias',
|
||||
disabled: false,
|
||||
|
@ -915,7 +915,9 @@ describe('SearchSource', () => {
|
|||
"negate": false,
|
||||
},
|
||||
"query": Object {
|
||||
"q": "query",
|
||||
"query_string": Object {
|
||||
"query": "query",
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
|
|
|
@ -120,9 +120,11 @@ describe('brushEvent', () => {
|
|||
|
||||
if (filter.length) {
|
||||
const rangeFilter = filter[0] as RangeFilter;
|
||||
expect(rangeFilter.range.time.gte).toBe(new Date(JAN_01_2014).toISOString());
|
||||
expect(rangeFilter.query.range.time.gte).toBe(new Date(JAN_01_2014).toISOString());
|
||||
// Set to a baseline timezone for comparison.
|
||||
expect(rangeFilter.range.time.lt).toBe(new Date(JAN_01_2014 + DAY_IN_MS).toISOString());
|
||||
expect(rangeFilter.query.range.time.lt).toBe(
|
||||
new Date(JAN_01_2014 + DAY_IN_MS).toISOString()
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -150,9 +152,11 @@ describe('brushEvent', () => {
|
|||
|
||||
if (filter.length) {
|
||||
const rangeFilter = filter[0] as RangeFilter;
|
||||
expect(rangeFilter.range.anotherTimeField.gte).toBe(moment(rangeBegin).toISOString());
|
||||
expect(rangeFilter.range.anotherTimeField.lt).toBe(moment(rangeEnd).toISOString());
|
||||
expect(rangeFilter.range.anotherTimeField).toHaveProperty(
|
||||
expect(rangeFilter.query.range.anotherTimeField.gte).toBe(
|
||||
moment(rangeBegin).toISOString()
|
||||
);
|
||||
expect(rangeFilter.query.range.anotherTimeField.lt).toBe(moment(rangeEnd).toISOString());
|
||||
expect(rangeFilter.query.range.anotherTimeField).toHaveProperty(
|
||||
'format',
|
||||
'strict_date_optional_time'
|
||||
);
|
||||
|
@ -187,9 +191,9 @@ describe('brushEvent', () => {
|
|||
|
||||
if (filter.length) {
|
||||
const rangeFilter = filter[0] as RangeFilter;
|
||||
expect(rangeFilter.range.numberField.gte).toBe(1);
|
||||
expect(rangeFilter.range.numberField.lt).toBe(4);
|
||||
expect(rangeFilter.range.numberField).not.toHaveProperty('format');
|
||||
expect(rangeFilter.query.range.numberField.gte).toBe(1);
|
||||
expect(rangeFilter.query.range.numberField.lt).toBe(4);
|
||||
expect(rangeFilter.query.range.numberField).not.toHaveProperty('format');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -86,7 +86,7 @@ describe('createFiltersFromValueClick', () => {
|
|||
const filters = await createFiltersFromValueClickAction({ data: dataPoints });
|
||||
|
||||
expect(filters.length).toEqual(1);
|
||||
expect(filters[0].query?.match_phrase.bytes).toEqual('2048');
|
||||
expect(filters[0].query?.match_phrase?.bytes).toEqual('2048');
|
||||
});
|
||||
|
||||
test('handles an event when aggregations type is not terms', async () => {
|
||||
|
@ -95,8 +95,8 @@ describe('createFiltersFromValueClick', () => {
|
|||
expect(filters.length).toEqual(1);
|
||||
|
||||
const [rangeFilter] = filters as RangeFilter[];
|
||||
expect(rangeFilter.range.bytes.gte).toEqual(2048);
|
||||
expect(rangeFilter.range.bytes.lt).toEqual(2078);
|
||||
expect(rangeFilter.query.range.bytes.gte).toEqual(2048);
|
||||
expect(rangeFilter.query.range.bytes.lt).toEqual(2078);
|
||||
});
|
||||
|
||||
test('handles non-unique filters', async () => {
|
||||
|
|
|
@ -16,7 +16,6 @@ import {
|
|||
isExistsFilter,
|
||||
isFilterPinned,
|
||||
isMatchAllFilter,
|
||||
isMissingFilter,
|
||||
isPhraseFilter,
|
||||
isPhrasesFilter,
|
||||
isQueryStringFilter,
|
||||
|
@ -114,7 +113,6 @@ export const esFilters = {
|
|||
isPhrasesFilter,
|
||||
isRangeFilter,
|
||||
isMatchAllFilter,
|
||||
isMissingFilter,
|
||||
isQueryStringFilter,
|
||||
isFilterPinned,
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ describe('Generate filters', () => {
|
|||
expect(filter.meta.index === INDEX_NAME);
|
||||
expect(filter.meta.negate).toBeFalsy();
|
||||
expect(isRangeFilter(filter)).toBeTruthy();
|
||||
expect(filter.range).toEqual({
|
||||
expect(filter.query.range).toEqual({
|
||||
[FIELD.name]: {
|
||||
gt: '192.168.0.0',
|
||||
lte: '192.168.255.255',
|
||||
|
|
|
@ -32,7 +32,7 @@ function getExistingFilter(
|
|||
if (!filter) return;
|
||||
|
||||
if (fieldName === '_exists_' && isExistsFilter(filter)) {
|
||||
return filter.exists!.field === value;
|
||||
return filter.query.exists!.field === value;
|
||||
}
|
||||
|
||||
if (isPhraseFilter(filter)) {
|
||||
|
|
|
@ -23,11 +23,11 @@ describe('filter manager utilities', () => {
|
|||
filters = [
|
||||
null,
|
||||
[
|
||||
{ meta: { index: 'logstash-*' }, exists: { field: '_type' } },
|
||||
{ meta: { index: 'logstash-*' }, missing: { field: '_type' } },
|
||||
{ meta: { index: 'logstash-*' }, query: { exists: { field: '_type' } } },
|
||||
{ meta: { index: 'logstash-*' }, query: { exists: { field: '_type' } } },
|
||||
],
|
||||
{ meta: { index: 'logstash-*' }, query: { query_string: { query: 'foo:bar' } } },
|
||||
{ meta: { index: 'logstash-*' }, range: { bytes: { lt: 2048, gt: 1024 } } },
|
||||
{ meta: { index: 'logstash-*' }, query: { range: { bytes: { lt: 2048, gt: 1024 } } } },
|
||||
{
|
||||
meta: { index: 'logstash-*' },
|
||||
query: { match: { _type: { query: 'apache', type: 'phrase' } } },
|
||||
|
@ -47,7 +47,7 @@ describe('filter manager utilities', () => {
|
|||
expect(results[0].meta).toHaveProperty('key', '_type');
|
||||
expect(results[0].meta).toHaveProperty('value', 'exists');
|
||||
expect(results[1].meta).toHaveProperty('key', '_type');
|
||||
expect(results[1].meta).toHaveProperty('value', 'missing');
|
||||
expect(results[1].meta).toHaveProperty('value', 'exists');
|
||||
expect(results[2].meta).toHaveProperty('key', 'query');
|
||||
expect(results[2].meta).toHaveProperty('value', 'foo:bar');
|
||||
expect(results[3].meta).toHaveProperty('key', 'bytes');
|
||||
|
|
|
@ -7,9 +7,13 @@
|
|||
*/
|
||||
|
||||
import { compact, flatten } from 'lodash';
|
||||
import { Filter } from '@kbn/es-query';
|
||||
import { Filter, migrateFilter } from '@kbn/es-query';
|
||||
import { mapFilter } from './map_filter';
|
||||
|
||||
export const mapAndFlattenFilters = (filters: Filter[]) => {
|
||||
return compact(flatten(filters)).map((item: Filter) => mapFilter(item));
|
||||
return compact(flatten(filters))
|
||||
.map((filter) => {
|
||||
return migrateFilter(filter);
|
||||
})
|
||||
.map((item: Filter) => mapFilter(item));
|
||||
};
|
||||
|
|
|
@ -33,7 +33,10 @@ describe('filter manager utilities', () => {
|
|||
});
|
||||
|
||||
test('should map exists filters', async () => {
|
||||
const before: any = { meta: { index: 'logstash-*' }, exists: { field: '@timestamp' } };
|
||||
const before: any = {
|
||||
meta: { index: 'logstash-*' },
|
||||
query: { exists: { field: '@timestamp' } },
|
||||
};
|
||||
const after = mapFilter(before as Filter);
|
||||
|
||||
expect(after).toHaveProperty('meta');
|
||||
|
@ -44,26 +47,14 @@ describe('filter manager utilities', () => {
|
|||
expect(after.meta).toHaveProperty('negate', false);
|
||||
});
|
||||
|
||||
test('should map missing filters', async () => {
|
||||
const before: any = { meta: { index: 'logstash-*' }, missing: { field: '@timestamp' } };
|
||||
const after = mapFilter(before as Filter);
|
||||
|
||||
expect(after).toHaveProperty('meta');
|
||||
expect(after.meta).toHaveProperty('key', '@timestamp');
|
||||
expect(after.meta).toHaveProperty('value');
|
||||
expect(getDisplayName(after)).toBe('missing');
|
||||
expect(after.meta).toHaveProperty('disabled', false);
|
||||
expect(after.meta).toHaveProperty('negate', false);
|
||||
});
|
||||
|
||||
test('should map json filter', async () => {
|
||||
const before: any = { meta: { index: 'logstash-*' }, query: { match_all: {} } };
|
||||
const before: any = { meta: { index: 'logstash-*' }, query: { test: {} } };
|
||||
const after = mapFilter(before as Filter);
|
||||
|
||||
expect(after).toHaveProperty('meta');
|
||||
expect(after.meta).toHaveProperty('key', 'query');
|
||||
expect(after.meta).toHaveProperty('value');
|
||||
expect(getDisplayName(after)).toBe('{"match_all":{}}');
|
||||
expect(getDisplayName(after)).toBe('{"test":{}}');
|
||||
expect(after.meta).toHaveProperty('disabled', false);
|
||||
expect(after.meta).toHaveProperty('negate', false);
|
||||
});
|
||||
|
|
|
@ -15,7 +15,6 @@ import { mapPhrase } from './mappers/map_phrase';
|
|||
import { mapPhrases } from './mappers/map_phrases';
|
||||
import { mapRange } from './mappers/map_range';
|
||||
import { mapExists } from './mappers/map_exists';
|
||||
import { mapMissing } from './mappers/map_missing';
|
||||
import { mapQueryString } from './mappers/map_query_string';
|
||||
import { mapDefault } from './mappers/map_default';
|
||||
import { generateMappingChain } from './generate_mapping_chain';
|
||||
|
@ -44,7 +43,6 @@ export function mapFilter(filter: Filter) {
|
|||
mapPhrase,
|
||||
mapPhrases,
|
||||
mapExists,
|
||||
mapMissing,
|
||||
mapQueryString,
|
||||
mapDefault,
|
||||
];
|
||||
|
|
|
@ -14,7 +14,7 @@ export const mapExists = (filter: Filter) => {
|
|||
return {
|
||||
type: FILTERS.EXISTS,
|
||||
value: FILTERS.EXISTS,
|
||||
key: get(filter, 'exists.field'),
|
||||
key: get(filter, 'query.exists.field'),
|
||||
};
|
||||
}
|
||||
throw filter;
|
||||
|
|
|
@ -15,7 +15,7 @@ describe('filter_manager/lib', () => {
|
|||
|
||||
beforeEach(() => {
|
||||
filter = {
|
||||
match_all: {},
|
||||
query: { match_all: {} },
|
||||
meta: {
|
||||
alias: null,
|
||||
negate: true,
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { mapMissing } from './map_missing';
|
||||
import { MissingFilter, buildEmptyFilter } from '../../../../../common';
|
||||
|
||||
describe('filter manager utilities', () => {
|
||||
describe('mapMissing()', () => {
|
||||
test('should return the key and value for matching filters', async () => {
|
||||
const filter: MissingFilter = {
|
||||
missing: { field: '_type' },
|
||||
...buildEmptyFilter(true),
|
||||
};
|
||||
const result = mapMissing(filter);
|
||||
|
||||
expect(result).toHaveProperty('key', '_type');
|
||||
expect(result).toHaveProperty('value', 'missing');
|
||||
});
|
||||
|
||||
test('should return undefined for none matching', async (done) => {
|
||||
const filter = buildEmptyFilter(true);
|
||||
|
||||
try {
|
||||
mapMissing(filter);
|
||||
} catch (e) {
|
||||
expect(e).toBe(filter);
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,21 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { Filter, isMissingFilter, FILTERS } from '@kbn/es-query';
|
||||
|
||||
export const mapMissing = (filter: Filter) => {
|
||||
if (isMissingFilter(filter)) {
|
||||
return {
|
||||
type: FILTERS.MISSING,
|
||||
value: FILTERS.MISSING,
|
||||
key: filter.missing.field,
|
||||
};
|
||||
}
|
||||
|
||||
throw filter;
|
||||
};
|
|
@ -14,7 +14,7 @@ describe('filter manager utilities', () => {
|
|||
test('should return the key and value for matching filters with gt/lt', async () => {
|
||||
const filter = {
|
||||
meta: { index: 'logstash-*' } as FilterMeta,
|
||||
range: { bytes: { lt: 2048, gt: 1024 } },
|
||||
query: { range: { bytes: { lt: 2048, gt: 1024 } } },
|
||||
} as RangeFilter;
|
||||
const result = mapRange(filter);
|
||||
|
||||
|
|
|
@ -22,14 +22,15 @@ const getFormattedValueFn = (left: any, right: any) => {
|
|||
};
|
||||
};
|
||||
|
||||
const getFirstRangeKey = (filter: RangeFilter) => filter.range && Object.keys(filter.range)[0];
|
||||
const getRangeByKey = (filter: RangeFilter, key: string) => get(filter, ['range', key]);
|
||||
const getFirstRangeKey = (filter: RangeFilter) =>
|
||||
filter.query.range && Object.keys(filter.query.range)[0];
|
||||
const getRangeByKey = (filter: RangeFilter, key: string) => get(filter.query, ['range', key]);
|
||||
|
||||
function getParams(filter: RangeFilter) {
|
||||
const isScriptedRange = isScriptedRangeFilter(filter);
|
||||
const key: string = (isScriptedRange ? filter.meta.field : getFirstRangeKey(filter)) || '';
|
||||
const params: any = isScriptedRange
|
||||
? get(filter, 'script.script.params')
|
||||
? get(filter.query, 'script.script.params')
|
||||
: getRangeByKey(filter, key);
|
||||
|
||||
let left = hasIn(params, 'gte') ? params.gte : params.gt;
|
||||
|
|
|
@ -14,11 +14,11 @@ describe('sortFilters', () => {
|
|||
test('Not sort two application level filters', () => {
|
||||
const f1 = {
|
||||
$state: { store: FilterStateStore.APP_STATE },
|
||||
...buildQueryFilter({ _type: { match: { query: 'apache', type: 'phrase' } } }, 'index', ''),
|
||||
...buildQueryFilter({ query_string: { query: 'apache' } }, 'index', ''),
|
||||
};
|
||||
const f2 = {
|
||||
$state: { store: FilterStateStore.APP_STATE },
|
||||
...buildQueryFilter({ _type: { match: { query: 'apache', type: 'phrase' } } }, 'index', ''),
|
||||
...buildQueryFilter({ query_string: { query: 'apache' } }, 'index', ''),
|
||||
};
|
||||
|
||||
const filters = [f1, f2].sort(sortFilters);
|
||||
|
@ -28,11 +28,11 @@ describe('sortFilters', () => {
|
|||
test('Not sort two global level filters', () => {
|
||||
const f1 = {
|
||||
$state: { store: FilterStateStore.GLOBAL_STATE },
|
||||
...buildQueryFilter({ _type: { match: { query: 'apache', type: 'phrase' } } }, 'index', ''),
|
||||
...buildQueryFilter({ query_string: { query: 'apache' } }, 'index', ''),
|
||||
};
|
||||
const f2 = {
|
||||
$state: { store: FilterStateStore.GLOBAL_STATE },
|
||||
...buildQueryFilter({ _type: { match: { query: 'apache', type: 'phrase' } } }, 'index', ''),
|
||||
...buildQueryFilter({ query_string: { query: 'apache' } }, 'index', ''),
|
||||
};
|
||||
|
||||
const filters = [f1, f2].sort(sortFilters);
|
||||
|
@ -42,11 +42,11 @@ describe('sortFilters', () => {
|
|||
test('Move global level filter to the beginning of the array', () => {
|
||||
const f1 = {
|
||||
$state: { store: FilterStateStore.APP_STATE },
|
||||
...buildQueryFilter({ _type: { match: { query: 'apache', type: 'phrase' } } }, 'index', ''),
|
||||
...buildQueryFilter({ query_string: { query: 'apache' } }, 'index', ''),
|
||||
};
|
||||
const f2 = {
|
||||
$state: { store: FilterStateStore.GLOBAL_STATE },
|
||||
...buildQueryFilter({ _type: { match: { query: 'apache', type: 'phrase' } } }, 'index', ''),
|
||||
...buildQueryFilter({ query_string: { query: 'apache' } }, 'index', ''),
|
||||
};
|
||||
|
||||
const filters = [f1, f2].sort(sortFilters);
|
||||
|
|
|
@ -11,15 +11,15 @@ import { Filter } from '../../../../common';
|
|||
export function getFiltersArray(): Filter[] {
|
||||
return [
|
||||
{
|
||||
query: { match: { extension: { query: 'jpg', type: 'phrase' } } },
|
||||
query: { match: { extension: { query: 'jpg' } } },
|
||||
meta: { index: 'logstash-*', negate: false, disabled: false, alias: null },
|
||||
},
|
||||
{
|
||||
query: { match: { '@tags': { query: 'info', type: 'phrase' } } },
|
||||
query: { match: { '@tags': { query: 'info' } } },
|
||||
meta: { index: 'logstash-*', negate: false, disabled: false, alias: null },
|
||||
},
|
||||
{
|
||||
query: { match: { _type: { query: 'nginx', type: 'phrase' } } },
|
||||
query: { match: { _type: { query: 'nginx' } } },
|
||||
meta: { index: 'logstash-*', negate: false, disabled: false, alias: null },
|
||||
},
|
||||
];
|
||||
|
|
|
@ -30,7 +30,7 @@ describe('changeTimeFilter()', () => {
|
|||
const lt = 1388646000000;
|
||||
|
||||
test('should change the timefilter to match the range gt/lt', () => {
|
||||
const filter: any = { range: { '@timestamp': { gt, lt } } };
|
||||
const filter: any = { query: { range: { '@timestamp': { gt, lt } } } };
|
||||
changeTimeFilter(timefilter, filter as RangeFilter);
|
||||
|
||||
const { to, from } = timefilter.getTime();
|
||||
|
@ -40,7 +40,7 @@ describe('changeTimeFilter()', () => {
|
|||
});
|
||||
|
||||
test('should change the timefilter to match the range gte/lte', () => {
|
||||
const filter: any = { range: { '@timestamp': { gte: gt, lte: lt } } };
|
||||
const filter: any = { query: { range: { '@timestamp': { gte: gt, lte: lt } } } };
|
||||
changeTimeFilter(timefilter, filter as RangeFilter);
|
||||
|
||||
const { to, from } = timefilter.getTime();
|
||||
|
|
|
@ -13,8 +13,8 @@ import { TimefilterContract } from '../../timefilter';
|
|||
import { TimeRange } from '../../../../common';
|
||||
|
||||
export function convertRangeFilterToTimeRange(filter: RangeFilter) {
|
||||
const key = keys(filter.range)[0];
|
||||
const values = filter.range[key];
|
||||
const key = keys(filter.query.range)[0];
|
||||
const values = filter.query.range[key];
|
||||
|
||||
return {
|
||||
from: moment(values.gt || values.gte),
|
||||
|
|
|
@ -28,11 +28,7 @@ describe('filter manager utilities', () => {
|
|||
describe('extractTimeFilter()', () => {
|
||||
test('should detect timeFilter', async () => {
|
||||
const filters: Filter[] = [
|
||||
buildQueryFilter(
|
||||
{ _type: { match: { query: 'apache', type: 'phrase' } } },
|
||||
'logstash-*',
|
||||
''
|
||||
),
|
||||
buildQueryFilter({ query_string: { query: 'apache' } }, 'logstash-*', ''),
|
||||
buildRangeFilter(
|
||||
{ name: 'time' } as IFieldType,
|
||||
{ gt: 1388559600000, lt: 1388646000000 },
|
||||
|
@ -47,11 +43,7 @@ describe('filter manager utilities', () => {
|
|||
|
||||
test("should not return timeFilter when name doesn't match", async () => {
|
||||
const filters: Filter[] = [
|
||||
buildQueryFilter(
|
||||
{ _type: { match: { query: 'apache', type: 'phrase' } } },
|
||||
'logstash-*',
|
||||
''
|
||||
),
|
||||
buildQueryFilter({ query_string: { query: 'apache' } }, 'logstash-*', ''),
|
||||
buildRangeFilter(
|
||||
{ name: '@timestamp' } as IFieldType,
|
||||
{ from: 1, to: 2 },
|
||||
|
@ -67,11 +59,7 @@ describe('filter manager utilities', () => {
|
|||
|
||||
test('should not return a non range filter, even when names match', async () => {
|
||||
const filters: Filter[] = [
|
||||
buildQueryFilter(
|
||||
{ _type: { match: { query: 'apache', type: 'phrase' } } },
|
||||
'logstash-*',
|
||||
''
|
||||
),
|
||||
buildQueryFilter({ query_string: { query: 'apache' } }, 'logstash-*', ''),
|
||||
buildPhraseFilter({ name: 'time' } as IFieldType, 'banana', indexPattern),
|
||||
];
|
||||
const result = await extractTimeFilter('time', filters);
|
||||
|
|
|
@ -16,7 +16,7 @@ export function extractTimeFilter(timeFieldName: string, filters: Filter[]) {
|
|||
let key;
|
||||
|
||||
if (isRangeFilter(obj)) {
|
||||
key = keys(obj.range)[0];
|
||||
key = keys(obj.query.range)[0];
|
||||
}
|
||||
|
||||
return Boolean(key && key === timeFieldName);
|
||||
|
|
|
@ -148,10 +148,9 @@ describe('Test Discover Context State', () => {
|
|||
"value": [Function],
|
||||
},
|
||||
"query": Object {
|
||||
"match": Object {
|
||||
"match_phrase": Object {
|
||||
"extension": Object {
|
||||
"query": "jpg",
|
||||
"type": "phrase",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -173,10 +172,9 @@ describe('Test Discover Context State', () => {
|
|||
"value": [Function],
|
||||
},
|
||||
"query": Object {
|
||||
"match": Object {
|
||||
"match_phrase": Object {
|
||||
"extension": Object {
|
||||
"query": "png",
|
||||
"type": "phrase",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -185,7 +183,7 @@ describe('Test Discover Context State', () => {
|
|||
`);
|
||||
state.flushToUrl();
|
||||
expect(getCurrentUrl()).toMatchInlineSnapshot(
|
||||
`"/#?_g=(filters:!(('$state':(store:globalState),meta:(alias:!n,disabled:!f,index:'logstash-*',key:extension,negate:!f,params:(query:jpg),type:phrase),query:(match:(extension:(query:jpg,type:phrase))))))&_a=(columns:!(_source),filters:!(('$state':(store:appState),meta:(alias:!n,disabled:!f,index:'logstash-*',key:extension,negate:!t,params:(query:png),type:phrase),query:(match:(extension:(query:png,type:phrase))))),predecessorCount:4,sort:!(!(time,desc)),successorCount:4)"`
|
||||
`"/#?_g=(filters:!(('$state':(store:globalState),meta:(alias:!n,disabled:!f,index:'logstash-*',key:extension,negate:!f,params:(query:jpg),type:phrase),query:(match_phrase:(extension:(query:jpg))))))&_a=(columns:!(_source),filters:!(('$state':(store:appState),meta:(alias:!n,disabled:!f,index:'logstash-*',key:extension,negate:!t,params:(query:png),type:phrase),query:(match_phrase:(extension:(query:png))))),predecessorCount:4,sort:!(!(time,desc)),successorCount:4)"`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -57,8 +57,8 @@ describe('RangeFilterManager', function () {
|
|||
expect(newFilter.meta.index).to.be(indexPatternId);
|
||||
expect(newFilter.meta.controlledBy).to.be(controlId);
|
||||
expect(newFilter.meta.key).to.be('field1');
|
||||
expect(newFilter).to.have.property('range');
|
||||
expect(JSON.stringify(newFilter.range, null, '')).to.be('{"field1":{"gte":1,"lte":3}}');
|
||||
expect(newFilter.query).to.have.property('range');
|
||||
expect(JSON.stringify(newFilter.query.range, null, '')).to.be('{"field1":{"gte":1,"lte":3}}');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -102,10 +102,12 @@ describe('RangeFilterManager', function () {
|
|||
test('should extract value from range filter', function () {
|
||||
filterManager.setMockFilters([
|
||||
{
|
||||
range: {
|
||||
field1: {
|
||||
gt: 1,
|
||||
lt: 3,
|
||||
query: {
|
||||
range: {
|
||||
field1: {
|
||||
gt: 1,
|
||||
lt: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
meta: {} as RangeFilterMeta,
|
||||
|
@ -122,10 +124,12 @@ describe('RangeFilterManager', function () {
|
|||
test('should return undefined when filter value can not be extracted from Kibana filter', function () {
|
||||
filterManager.setMockFilters([
|
||||
{
|
||||
range: {
|
||||
myFieldWhichIsNotField1: {
|
||||
gte: 1,
|
||||
lte: 3,
|
||||
query: {
|
||||
range: {
|
||||
myFieldWhichIsNotField1: {
|
||||
gte: 1,
|
||||
lte: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
meta: {} as RangeFilterMeta,
|
||||
|
|
|
@ -68,10 +68,10 @@ export class RangeFilterManager extends FilterManager {
|
|||
}
|
||||
|
||||
let range: RangeFilterParams;
|
||||
if (_.has(kbnFilters[0], 'script')) {
|
||||
range = _.get(kbnFilters[0], 'script.script.params');
|
||||
if (_.has(kbnFilters[0], 'query.script')) {
|
||||
range = _.get(kbnFilters[0], 'query.script.script.params');
|
||||
} else {
|
||||
range = _.get(kbnFilters[0], ['range', this.fieldName]);
|
||||
range = _.get(kbnFilters[0], ['query', 'range', this.fieldName]);
|
||||
}
|
||||
|
||||
if (!range) {
|
||||
|
|
|
@ -124,14 +124,16 @@ describe('query', () => {
|
|||
test('returns doc with global query', async () => {
|
||||
req.body.filters = [
|
||||
{
|
||||
bool: {
|
||||
must: [
|
||||
{
|
||||
term: {
|
||||
host: 'example',
|
||||
query: {
|
||||
bool: {
|
||||
must: [
|
||||
{
|
||||
term: {
|
||||
host: 'example',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
@ -234,14 +236,16 @@ describe('query', () => {
|
|||
test('returns doc with panel filter and global', async () => {
|
||||
req.body.filters = [
|
||||
{
|
||||
bool: {
|
||||
must: [
|
||||
{
|
||||
term: {
|
||||
host: 'example',
|
||||
query: {
|
||||
bool: {
|
||||
must: [
|
||||
{
|
||||
term: {
|
||||
host: 'example',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
|
|
@ -12,17 +12,19 @@ const body = JSON.parse(`
|
|||
{
|
||||
"filters": [
|
||||
{
|
||||
"bool": {
|
||||
"must": [
|
||||
{
|
||||
"query_string": {
|
||||
"analyze_wildcard": true,
|
||||
"query": "*"
|
||||
}
|
||||
}
|
||||
],
|
||||
"must_not": []
|
||||
}
|
||||
"query": {
|
||||
"bool": {
|
||||
"must": [
|
||||
{
|
||||
"query_string": {
|
||||
"analyze_wildcard": true,
|
||||
"query": "*"
|
||||
}
|
||||
}
|
||||
],
|
||||
"must_not": []
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"panels": [
|
||||
|
|
|
@ -358,11 +358,13 @@ export class VegaBaseView {
|
|||
timeFieldName: '*',
|
||||
filters: [
|
||||
{
|
||||
range: {
|
||||
'*': {
|
||||
mode,
|
||||
gte: from,
|
||||
lte: to,
|
||||
query: {
|
||||
range: {
|
||||
'*': {
|
||||
mode,
|
||||
gte: from,
|
||||
lte: to,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -84,8 +84,10 @@ const existFilter: Filter = {
|
|||
key: 'transaction.marks.navigationTiming.fetchStart',
|
||||
value: 'exists',
|
||||
},
|
||||
exists: {
|
||||
field: 'transaction.marks.navigationTiming.fetchStart',
|
||||
query: {
|
||||
exists: {
|
||||
field: 'transaction.marks.navigationTiming.fetchStart',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -108,7 +110,7 @@ export const useMapFilters = (): Filter[] => {
|
|||
} = uxUiFilters;
|
||||
|
||||
return useMemo(() => {
|
||||
const filters = [existFilter];
|
||||
const filters: Filter[] = [existFilter];
|
||||
if (serviceName) {
|
||||
filters.push(getMatchFilter(SERVICE_NAME, serviceName));
|
||||
}
|
||||
|
|
|
@ -349,11 +349,13 @@ function getMockTimeRangeFilter(): RangeFilter {
|
|||
negate: false,
|
||||
alias: null,
|
||||
},
|
||||
range: {
|
||||
order_date: {
|
||||
gte: '2020-03-23T13:10:29.665Z',
|
||||
lt: '2020-03-23T13:10:36.736Z',
|
||||
format: 'strict_date_optional_time',
|
||||
query: {
|
||||
range: {
|
||||
order_date: {
|
||||
gte: '2020-03-23T13:10:29.665Z',
|
||||
lt: '2020-03-23T13:10:36.736Z',
|
||||
format: 'strict_date_optional_time',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -234,10 +234,12 @@ describe('"Explore underlying data" panel action', () => {
|
|||
lte: to,
|
||||
},
|
||||
},
|
||||
range: {
|
||||
[timeFieldName]: {
|
||||
gte: from,
|
||||
lte: to,
|
||||
query: {
|
||||
range: {
|
||||
[timeFieldName]: {
|
||||
gte: from,
|
||||
lte: to,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -215,7 +215,7 @@ describe('IndexPattern Field Item', () => {
|
|||
query: { query: 'geo.src : "US"', language: 'kuery' },
|
||||
filters: [
|
||||
{
|
||||
match: { phrase: { 'geo.dest': 'US' } },
|
||||
query: { match: { phrase: { 'geo.dest': 'US' } } },
|
||||
},
|
||||
],
|
||||
});
|
||||
|
|
|
@ -125,8 +125,10 @@ describe('getESFilters', () => {
|
|||
index: 'indexPatternId',
|
||||
negate: true,
|
||||
},
|
||||
exists: {
|
||||
field: 'machine.os',
|
||||
query: {
|
||||
exists: {
|
||||
field: 'machine.os',
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
|
|
@ -505,7 +505,7 @@ export class LensAttributes {
|
|||
const existFilter = filter as ExistsFilter;
|
||||
|
||||
if (isExistsFilter(existFilter)) {
|
||||
const fieldName = existFilter.exists?.field;
|
||||
const fieldName = existFilter.query.exists?.field;
|
||||
const kql = `${fieldName} : *`;
|
||||
if (baseFilters.length > 0) {
|
||||
baseFilters += ` and ${kql}`;
|
||||
|
|
|
@ -66,7 +66,7 @@ export function FilterExpanded({
|
|||
queryFilters.push(qFilter.query);
|
||||
}
|
||||
if (isExistsFilter(qFilter)) {
|
||||
queryFilters.push({ exists: qFilter.exists } as QueryDslQueryContainer);
|
||||
queryFilters.push({ exists: qFilter.query.exists } as QueryDslQueryContainer);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -38,8 +38,8 @@ export function ReportDefinitionField({ series, field, seriesConfig, onChange }:
|
|||
filtersN.push(qFilter.query);
|
||||
}
|
||||
const existFilter = qFilter as ExistsFilter;
|
||||
if (existFilter.exists) {
|
||||
filtersN.push({ exists: existFilter.exists });
|
||||
if (existFilter.query.exists) {
|
||||
filtersN.push({ exists: existFilter.query.exists });
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -395,7 +395,7 @@ export class AlertsClient {
|
|||
esQuery == null ? { query: ``, language: 'kuery' } : esQuery,
|
||||
[
|
||||
authzFilter as unknown as Filter,
|
||||
{ term: { [SPACE_IDS]: alertSpaceId } } as unknown as Filter,
|
||||
{ query: { term: { [SPACE_IDS]: alertSpaceId } } } as unknown as Filter,
|
||||
],
|
||||
config
|
||||
);
|
||||
|
|
|
@ -216,8 +216,10 @@ describe('get_filter', () => {
|
|||
};
|
||||
|
||||
const exists: Partial<Filter> = {
|
||||
exists: {
|
||||
field: 'host.hostname',
|
||||
query: {
|
||||
exists: {
|
||||
field: 'host.hostname',
|
||||
},
|
||||
},
|
||||
} as Partial<Filter>;
|
||||
|
||||
|
|
|
@ -65,10 +65,9 @@ const state: State = {
|
|||
},
|
||||
},
|
||||
query: {
|
||||
match: {
|
||||
match_phrase: {
|
||||
'host.os.name': {
|
||||
query: 'Linux',
|
||||
type: 'phrase',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -121,10 +120,9 @@ const state: State = {
|
|||
type: 'phrase',
|
||||
},
|
||||
query: {
|
||||
match: {
|
||||
match_phrase: {
|
||||
'source.port': {
|
||||
query: '30045',
|
||||
type: 'phrase',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -256,7 +254,7 @@ describe('StatefulTopN', () => {
|
|||
key: 'host.os.name',
|
||||
params: { query: 'Linux' },
|
||||
},
|
||||
query: { match: { 'host.os.name': { query: 'Linux', type: 'phrase' } } },
|
||||
query: { match_phrase: { 'host.os.name': { query: 'Linux' } } },
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
|
|
@ -52,8 +52,10 @@ describe('alerts default_config', () => {
|
|||
type: 'exists',
|
||||
value: 'exists',
|
||||
},
|
||||
exists: {
|
||||
field: 'signal.rule.threat_mapping',
|
||||
query: {
|
||||
exists: {
|
||||
field: 'signal.rule.threat_mapping',
|
||||
},
|
||||
},
|
||||
};
|
||||
expect(filters).toHaveLength(1);
|
||||
|
|
|
@ -130,8 +130,7 @@ export const buildShowBuildingBlockFilter = (showBuildingBlockAlerts: boolean):
|
|||
key: 'signal.rule.building_block_type',
|
||||
value: 'exists',
|
||||
},
|
||||
// @ts-expect-error TODO: Rework parent typings to support ExistsFilter[]
|
||||
exists: { field: 'signal.rule.building_block_type' },
|
||||
query: { exists: { field: 'signal.rule.building_block_type' } },
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -147,8 +146,7 @@ export const buildThreatMatchFilter = (showOnlyThreatIndicatorAlerts: boolean):
|
|||
type: 'exists',
|
||||
value: 'exists',
|
||||
},
|
||||
// @ts-expect-error TODO: Rework parent typings to support ExistsFilter[]
|
||||
exists: { field: 'signal.rule.threat_mapping' },
|
||||
query: { exists: { field: 'signal.rule.threat_mapping' } },
|
||||
},
|
||||
]
|
||||
: [];
|
||||
|
@ -268,8 +266,7 @@ export const buildShowBuildingBlockFilterRuleRegistry = (
|
|||
key: 'kibana.rule.building_block_type',
|
||||
value: 'exists',
|
||||
},
|
||||
// @ts-expect-error TODO: Rework parent typings to support ExistsFilter[]
|
||||
exists: { field: 'kibana.rule.building_block_type' },
|
||||
query: { exists: { field: 'kibana.rule.building_block_type' } },
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
@ -98,7 +98,7 @@ describe('query_preview/helpers', () => {
|
|||
|
||||
expect(queryString).toEqual('host.name:*');
|
||||
expect(language).toEqual('kuery');
|
||||
expect(filters).toEqual([{ meta: { alias: '', disabled: false, negate: false } }]);
|
||||
expect(filters).toEqual([{ meta: { alias: '', disabled: false, negate: false }, query: {} }]);
|
||||
expect(queryFilter).toEqual({
|
||||
bool: {
|
||||
filter: [
|
||||
|
@ -124,7 +124,7 @@ describe('query_preview/helpers', () => {
|
|||
|
||||
expect(queryString).toEqual('host.name:*');
|
||||
expect(language).toEqual('kuery');
|
||||
expect(filters).toEqual([{ meta: { alias: '', disabled: false, negate: false } }]);
|
||||
expect(filters).toEqual([{ meta: { alias: '', disabled: false, negate: false }, query: {} }]);
|
||||
expect(queryFilter).toEqual({
|
||||
bool: {
|
||||
filter: [
|
||||
|
@ -150,7 +150,7 @@ describe('query_preview/helpers', () => {
|
|||
|
||||
expect(queryString).toEqual('host.name:*');
|
||||
expect(language).toEqual('kuery');
|
||||
expect(filters).toEqual([{ meta: { alias: '', disabled: false, negate: false } }]);
|
||||
expect(filters).toEqual([{ meta: { alias: '', disabled: false, negate: false }, query: {} }]);
|
||||
expect(queryFilter).toEqual({
|
||||
bool: {
|
||||
filter: [
|
||||
|
|
|
@ -79,7 +79,9 @@ describe('queryPreviewReducer', () => {
|
|||
|
||||
expect(update.language).toEqual('kuery');
|
||||
expect(update.queryString).toEqual('host.name:*');
|
||||
expect(update.filters).toEqual([{ meta: { alias: '', disabled: false, negate: false } }]);
|
||||
expect(update.filters).toEqual([
|
||||
{ meta: { alias: '', disabled: false, negate: false }, query: {} },
|
||||
]);
|
||||
});
|
||||
|
||||
test('should create the queryFilter if query type is not eql', () => {
|
||||
|
|
|
@ -290,7 +290,7 @@ describe('Combined Queries', () => {
|
|||
type: 'exists',
|
||||
value: 'exists',
|
||||
},
|
||||
exists: { field: 'host.name' },
|
||||
query: { exists: { field: 'host.name' } },
|
||||
} as Filter,
|
||||
],
|
||||
kqlQuery: { query: '', language: 'kuery' },
|
||||
|
@ -515,8 +515,10 @@ describe('Combined Queries', () => {
|
|||
key: 'nestedField.firstAttributes',
|
||||
value: 'exists',
|
||||
},
|
||||
exists: {
|
||||
field: 'nestedField.firstAttributes',
|
||||
query: {
|
||||
exists: {
|
||||
field: 'nestedField.firstAttributes',
|
||||
},
|
||||
},
|
||||
$state: {
|
||||
store: esFilters.FilterStateStore.APP_STATE,
|
||||
|
|
|
@ -126,7 +126,7 @@ describe('Epic Timeline', () => {
|
|||
type: 'exists',
|
||||
value: 'exists',
|
||||
},
|
||||
exists: { field: '@timestamp' },
|
||||
query: { exists: { field: '@timestamp' } },
|
||||
} as Filter,
|
||||
],
|
||||
indexNames: [],
|
||||
|
@ -264,13 +264,12 @@ describe('Epic Timeline', () => {
|
|||
type: 'phrase',
|
||||
value: null,
|
||||
},
|
||||
missing: null,
|
||||
query: '{"match_phrase":{"event.category":"file"}}',
|
||||
range: null,
|
||||
script: null,
|
||||
},
|
||||
{
|
||||
exists: '{"field":"@timestamp"}',
|
||||
query: '{"exists":{"field":"@timestamp"}}',
|
||||
match_all: null,
|
||||
meta: {
|
||||
alias: null,
|
||||
|
@ -282,8 +281,6 @@ describe('Epic Timeline', () => {
|
|||
type: 'exists',
|
||||
value: 'exists',
|
||||
},
|
||||
missing: null,
|
||||
query: null,
|
||||
range: null,
|
||||
script: null,
|
||||
},
|
||||
|
|
|
@ -392,27 +392,28 @@ export const convertTimelineAsInput = (
|
|||
},
|
||||
...(esFilters.isMatchAllFilter(basicFilter)
|
||||
? {
|
||||
match_all: convertToString((basicFilter as MatchAllFilter).match_all),
|
||||
query: {
|
||||
match_all: convertToString(
|
||||
(basicFilter as MatchAllFilter).query.match_all
|
||||
),
|
||||
},
|
||||
}
|
||||
: { match_all: null }),
|
||||
...(esFilters.isMissingFilter(basicFilter) && basicFilter.missing != null
|
||||
? { missing: convertToString(basicFilter.missing) }
|
||||
: { missing: null }),
|
||||
...(esFilters.isExistsFilter(basicFilter) && basicFilter.exists != null
|
||||
? { exists: convertToString(basicFilter.exists) }
|
||||
...(esFilters.isExistsFilter(basicFilter) && basicFilter.query.exists != null
|
||||
? { query: { exists: convertToString(basicFilter.query.exists) } }
|
||||
: { exists: null }),
|
||||
...((esFilters.isQueryStringFilter(basicFilter) ||
|
||||
get('query', basicFilter) != null) &&
|
||||
basicFilter.query != null
|
||||
? { query: convertToString(basicFilter.query) }
|
||||
: { query: null }),
|
||||
...(esFilters.isRangeFilter(basicFilter) && basicFilter.range != null
|
||||
? { range: convertToString(basicFilter.range) }
|
||||
...(esFilters.isRangeFilter(basicFilter) && basicFilter.query.range != null
|
||||
? { query: { range: convertToString(basicFilter.query.range) } }
|
||||
: { range: null }),
|
||||
...(isScriptedRangeFilter(basicFilter) &&
|
||||
basicFilter.script !=
|
||||
basicFilter.query.script !=
|
||||
null /* TODO remove it when PR50713 is merged || esFilters.isPhraseFilter(basicFilter) */
|
||||
? { script: convertToString(basicFilter.script) }
|
||||
? { query: { script: convertToString(basicFilter.query.script) } }
|
||||
: { script: null }),
|
||||
};
|
||||
})
|
||||
|
|
|
@ -288,7 +288,7 @@ describe('Combined Queries', () => {
|
|||
type: 'exists',
|
||||
value: 'exists',
|
||||
},
|
||||
exists: { field: 'host.name' },
|
||||
query: { exists: { field: 'host.name' } },
|
||||
} as Filter,
|
||||
],
|
||||
kqlQuery: { query: '', language: 'kuery' },
|
||||
|
@ -489,8 +489,10 @@ describe('Combined Queries', () => {
|
|||
key: 'nestedField.firstAttributes',
|
||||
value: 'exists',
|
||||
},
|
||||
exists: {
|
||||
field: 'nestedField.firstAttributes',
|
||||
query: {
|
||||
exists: {
|
||||
field: 'nestedField.firstAttributes',
|
||||
},
|
||||
},
|
||||
$state: {
|
||||
store: esFilters.FilterStateStore.APP_STATE,
|
||||
|
|
|
@ -120,7 +120,7 @@ export default function ({ getPageObjects, getService }) {
|
|||
const currentUrl = await browser.getCurrentUrl();
|
||||
const appState = currentUrl.substring(currentUrl.indexOf('_a='));
|
||||
expect(appState).to.equal(
|
||||
'_a=(filters:!((%27$state%27:(store:appState),meta:(alias:!n,disabled:!f,index:c698b940-e149-11e8-a35a-370a8516603a,key:machine.os.raw,negate:!f,params:(query:ios),type:phrase),query:(match:(machine.os.raw:(query:ios,type:phrase))))),query:(language:kuery,query:%27%27))'
|
||||
'_a=(filters:!((%27$state%27:(store:appState),meta:(alias:!n,disabled:!f,index:c698b940-e149-11e8-a35a-370a8516603a,key:machine.os.raw,negate:!f,params:(query:ios),type:phrase),query:(match_phrase:(machine.os.raw:(query:ios))))),query:(language:kuery,query:%27%27))'
|
||||
);
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue