Skip to content

Commit

Permalink
filter default queries
Browse files Browse the repository at this point in the history
  • Loading branch information
walterra committed Feb 20, 2024
1 parent 4eb9895 commit ba76eb8
Show file tree
Hide file tree
Showing 27 changed files with 282 additions and 107 deletions.
11 changes: 10 additions & 1 deletion x-pack/packages/ml/query_utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,17 @@

export { addExcludeFrozenToQuery } from './src/add_exclude_frozen_to_query';
export { buildBaseFilterCriteria } from './src/build_base_filter_criteria';
export { isDefaultQuery } from './src/default_query';
export { ES_CLIENT_TOTAL_HITS_RELATION } from './src/es_client_total_hits_relation';
export { getSafeAggregationName } from './src/get_safe_aggregation_name';
export { matchAllQuery, isMatchAllQuery } from './src/match_all_query';
export { isSimpleQuery } from './src/simple_query';
export { SEARCH_QUERY_LANGUAGE } from './src/types';
export type { SearchQueryLanguage } from './src/types';
export type {
FilterBasedSimpleQuery,
SavedSearchQuery,
SearchQueryLanguage,
SearchQueryVariant,
SimpleQuery,
} from './src/types';
export { getDefaultDSLQuery } from './src/get_default_query';
10 changes: 10 additions & 0 deletions x-pack/packages/ml/query_utils/src/__mocks__/simple_query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { SearchQueryVariant } from '../types';

export const simpleQueryMock: SearchQueryVariant = { query_string: { query: 'airline:AAL' } };
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import { Query } from '@kbn/es-query';

import { isDefaultQuery } from './default_query';
import { isFilterBasedDefaultQuery } from './filter_based_default_query';

/**
* Builds the base filter criteria used in queries,
* adding criteria for the time range and an optional query.
Expand Down Expand Up @@ -38,7 +41,12 @@ export function buildBaseFilterCriteria(
});
}

if (query && typeof query === 'object') {
if (
query &&
typeof query === 'object' &&
!isDefaultQuery(query) &&
!isFilterBasedDefaultQuery(query)
) {
filterCriteria.push(query);
}

Expand Down
19 changes: 19 additions & 0 deletions x-pack/packages/ml/query_utils/src/default_query.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { simpleQueryMock } from './__mocks__/simple_query';
import { isDefaultQuery } from './default_query';
import { matchAllQuery } from './match_all_query';
import { defaultSimpleQuery } from './simple_query';

describe('isDefaultQuery', () => {
it("should return if it's a default query", () => {
expect(isDefaultQuery(defaultSimpleQuery)).toBe(true);
expect(isDefaultQuery(matchAllQuery)).toBe(true);
expect(isDefaultQuery(simpleQueryMock)).toBe(false);
});
});
20 changes: 20 additions & 0 deletions x-pack/packages/ml/query_utils/src/default_query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { isFilterBasedSimpleQuery } from './filter_based_simple_query';
import { isMatchAllQuery } from './match_all_query';
import { isSimpleQuery } from './simple_query';
import type { SearchQueryVariant } from './types';

export function isDefaultQuery(query: SearchQueryVariant): boolean {
return (
isMatchAllQuery(query) ||
(isSimpleQuery(query) && query.query_string.query === '*') ||
(isFilterBasedSimpleQuery(query) &&
(query.bool.filter[0].query_string.query === '*' || isMatchAllQuery(query.bool.filter[0])))
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { isFilterBasedDefaultQuery } from './filter_based_default_query';
import { simpleQueryMock } from './__mocks__/simple_query';
import { matchAllQuery } from './match_all_query';
import { defaultSimpleQuery } from './simple_query';

describe('isFilterBasedDefaultQuery', () => {
it('should identify filter based default queries', () => {
expect(isFilterBasedDefaultQuery(defaultSimpleQuery)).toBe(false);
expect(isFilterBasedDefaultQuery(matchAllQuery)).toBe(false);
expect(isFilterBasedDefaultQuery(simpleQueryMock)).toBe(false);
expect(
isFilterBasedDefaultQuery({
bool: { filter: [simpleQueryMock], must: [], must_not: [], should: [] },
})
).toBe(false);
expect(
isFilterBasedDefaultQuery({
bool: { filter: [], must: [], must_not: [], should: [] },
})
).toBe(true);
expect(
isFilterBasedDefaultQuery({
bool: { filter: [matchAllQuery], must: [], must_not: [], should: [] },
})
).toBe(true);
expect(
isFilterBasedDefaultQuery({
bool: { filter: [], must: [matchAllQuery], must_not: [], should: [simpleQueryMock] },
})
).toBe(false);
expect(
isFilterBasedDefaultQuery({
bool: { filter: [], must: [matchAllQuery], must_not: [simpleQueryMock] },
})
).toBe(false);
expect(
isFilterBasedDefaultQuery({
bool: { filter: [], must: [matchAllQuery], must_not: [] },
})
).toBe(true);
});
});
35 changes: 35 additions & 0 deletions x-pack/packages/ml/query_utils/src/filter_based_default_query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { isPopulatedObject } from '@kbn/ml-is-populated-object';

import type { FilterBasedSimpleQuery } from './types';
import { isDefaultQuery } from './default_query';

const boolRequiredAttributes = ['filter', 'must', 'must_not'];
// const boolAttributes = ['filter', 'must', 'must_not', 'should'];

// should identify variants of
// `{ bool: { filter: [{ match_all: {} }], must: [], must_not: [], should: [] } }`
// `{ bool: { filter: [], must: [{ match_all: {} }], must_not: [] } }`
export function isFilterBasedDefaultQuery(arg: unknown): arg is FilterBasedSimpleQuery {
return (
isPopulatedObject(arg, ['bool']) &&
isPopulatedObject(arg.bool, boolRequiredAttributes) &&
Object.keys(arg.bool).every(
// should be either an empty array or an array with just 1 default query
(d) => {
if (!isPopulatedObject(arg.bool, [d])) return false;
const attr = arg.bool[d];
return (
Array.isArray(attr) &&
(attr.length === 0 || (attr.length === 1 && isDefaultQuery(attr[0])))
);
}
)
);
}
21 changes: 21 additions & 0 deletions x-pack/packages/ml/query_utils/src/filter_based_simple_query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { isPopulatedObject } from '@kbn/ml-is-populated-object';

import { isSimpleQuery } from './simple_query';
import type { FilterBasedSimpleQuery } from './types';

export function isFilterBasedSimpleQuery(arg: unknown): arg is FilterBasedSimpleQuery {
return (
isPopulatedObject(arg, ['bool']) &&
isPopulatedObject(arg.bool, ['filter']) &&
Array.isArray(arg.bool.filter) &&
arg.bool.filter.length === 1 &&
isSimpleQuery(arg.bool.filter[0])
);
}
16 changes: 16 additions & 0 deletions x-pack/packages/ml/query_utils/src/match_all_query.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { isMatchAllQuery, matchAllQuery } from './match_all_query';

describe('isMatchAllQuery', () => {
it("should return if it's a match_all query", () => {
expect(isMatchAllQuery(matchAllQuery)).toBe(true);
expect(isMatchAllQuery({ query_string: { query: '*' } })).toBe(false);
expect(isMatchAllQuery({ query_string: { query: 'airline:AAL' } })).toBe(false);
});
});
19 changes: 19 additions & 0 deletions x-pack/packages/ml/query_utils/src/match_all_query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { isPopulatedObject } from '@kbn/ml-is-populated-object';

export const matchAllQuery = { match_all: {} };

export function isMatchAllQuery(query: unknown): boolean {
return (
isPopulatedObject(query, ['match_all']) &&
typeof query.match_all === 'object' &&
query.match_all !== null &&
Object.keys(query.match_all).length === 0
);
}
18 changes: 18 additions & 0 deletions x-pack/packages/ml/query_utils/src/simple_query.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { simpleQueryMock } from './__mocks__/simple_query';
import { defaultSimpleQuery, isSimpleQuery } from './simple_query';
import { matchAllQuery } from './match_all_query';

describe('isSimpleQuery', () => {
it("should return if it's a simple query", () => {
expect(isSimpleQuery(defaultSimpleQuery)).toBe(true);
expect(isSimpleQuery(matchAllQuery)).toBe(false);
expect(isSimpleQuery(simpleQueryMock)).toBe(true);
});
});
16 changes: 16 additions & 0 deletions x-pack/packages/ml/query_utils/src/simple_query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { isPopulatedObject } from '@kbn/ml-is-populated-object';

import type { SimpleQuery } from './types';

export const defaultSimpleQuery: SimpleQuery = { query_string: { query: '*' } };

export function isSimpleQuery(arg: unknown): arg is SimpleQuery {
return isPopulatedObject(arg, ['query_string']);
}
19 changes: 19 additions & 0 deletions x-pack/packages/ml/query_utils/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* 2.0.
*/

import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';

/**
* Constant for kuery and lucene string
*/
Expand All @@ -17,3 +19,20 @@ export const SEARCH_QUERY_LANGUAGE = {
* Type for SearchQueryLanguage
*/
export type SearchQueryLanguage = typeof SEARCH_QUERY_LANGUAGE[keyof typeof SEARCH_QUERY_LANGUAGE];

export type SavedSearchQuery = object;

export interface SimpleQuery {
query_string: {
query: string;
default_operator?: estypes.QueryDslOperator;
};
}

export interface FilterBasedSimpleQuery {
bool: {
filter: [SimpleQuery];
};
}

export type SearchQueryVariant = FilterBasedSimpleQuery | SimpleQuery | SavedSearchQuery;
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ describe('query_utils', () => {
},
},
},
{ match_all: {} },
]);
});

Expand All @@ -142,7 +141,6 @@ describe('query_utils', () => {
},
},
},
{ match_all: {} },
{ term: { 'meta.cloud.instance_id.keyword': '1234' } },
]);
});
Expand All @@ -167,7 +165,6 @@ describe('query_utils', () => {
},
},
},
{ match_all: {} },
{ bool: { must_not: [{ term: { 'meta.cloud.instance_id.keyword': '1234' } }] } },
]);
});
Expand All @@ -193,7 +190,6 @@ describe('query_utils', () => {
},
},
},
{ match_all: {} },
{
term: {
'error.message': 'rate limit exceeded',
Expand Down Expand Up @@ -248,7 +244,6 @@ describe('query_utils', () => {
},
},
},
{ match_all: {} },
{
bool: {
must_not: [
Expand Down
3 changes: 2 additions & 1 deletion x-pack/plugins/transform/public/app/common/data_grid.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
*/

import type { DataView } from '@kbn/data-views-plugin/common';
import type { SimpleQuery } from '@kbn/ml-query-utils';

import { getPreviewTransformRequestBody, SimpleQuery } from '.';
import { getPreviewTransformRequestBody } from '.';
import { getIndexDevConsoleStatement, getTransformPreviewDevConsoleStatement } from './data_grid';

describe('Transform: Data Grid', () => {
Expand Down
7 changes: 1 addition & 6 deletions x-pack/plugins/transform/public/app/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,10 @@ export {
pivotGroupByFieldSupport,
PIVOT_SUPPORTED_GROUP_BY_AGGS,
} from './pivot_group_by';
export type { TransformConfigQuery, SimpleQuery } from './request';
export type { TransformConfigQuery } from './request';
export {
defaultQuery,
getPreviewTransformRequestBody,
getCreateTransformRequestBody,
getTransformConfigQuery,
getRequestPayload,
isDefaultQuery,
isMatchAllQuery,
isSimpleQuery,
matchAllQuery,
} from './request';
Loading

0 comments on commit ba76eb8

Please sign in to comment.