diff --git a/src/server/saved_objects/client/lib/search_dsl/__tests__/query_params.js b/src/server/saved_objects/client/lib/search_dsl/__tests__/query_params.js index d12be9edfe4aa37..9a257932933b66c 100644 --- a/src/server/saved_objects/client/lib/search_dsl/__tests__/query_params.js +++ b/src/server/saved_objects/client/lib/search_dsl/__tests__/query_params.js @@ -117,7 +117,6 @@ describe('searchDsl/queryParams', () => { simple_query_string: { query: 'y*', fields: [ - 'type.title', 'pending.title', 'saved.title' ] @@ -138,7 +137,6 @@ describe('searchDsl/queryParams', () => { simple_query_string: { query: 'y*', fields: [ - 'type.title^3', 'pending.title^3', 'saved.title^3' ] @@ -159,10 +157,8 @@ describe('searchDsl/queryParams', () => { simple_query_string: { query: 'y*', fields: [ - 'type.title', 'pending.title', 'saved.title', - 'type.title.raw', 'pending.title.raw', 'saved.title.raw', ] diff --git a/src/server/saved_objects/client/lib/search_dsl/experimental_filter/__snapshots__/convert.test.js.snap b/src/server/saved_objects/client/lib/search_dsl/experimental_filter/__snapshots__/convert.test.js.snap index e88f2f58ba9d3e4..b49bca89941c092 100644 --- a/src/server/saved_objects/client/lib/search_dsl/experimental_filter/__snapshots__/convert.test.js.snap +++ b/src/server/saved_objects/client/lib/search_dsl/experimental_filter/__snapshots__/convert.test.js.snap @@ -57,81 +57,33 @@ Object { }, }, Object { - "bool": Object { - "should": Array [ - Object { - "range": Object { - "visualize.created": Object { - "gt": undefined, - "gte": 2018-03-02T07:00:00.000Z, - "lt": 2018-03-03T07:00:00.000Z, - "lte": undefined, - }, - }, - }, - Object { - "range": Object { - "dashboard.created": Object { - "gt": undefined, - "gte": 2018-03-02T07:00:00.000Z, - "lt": 2018-03-03T07:00:00.000Z, - "lte": undefined, - }, - }, - }, - ], + "range": Object { + "updated_at": Object { + "gt": undefined, + "gte": 2018-03-02T07:00:00.000Z, + "lt": 2018-03-03T07:00:00.000Z, + "lte": undefined, + }, }, }, Object { - "bool": Object { - "should": Array [ - Object { - "range": Object { - "visualize.created": Object { - "gt": undefined, - "gte": 2018-02-25T07:00:00.000Z, - "lt": 2018-03-01T07:00:00.000Z, - "lte": undefined, - }, - }, - }, - Object { - "range": Object { - "dashboard.created": Object { - "gt": undefined, - "gte": 2018-02-25T07:00:00.000Z, - "lt": 2018-03-01T07:00:00.000Z, - "lte": undefined, - }, - }, - }, - ], + "range": Object { + "updated_at": Object { + "gt": undefined, + "gte": 2018-02-25T07:00:00.000Z, + "lt": 2018-03-01T07:00:00.000Z, + "lte": undefined, + }, }, }, Object { - "bool": Object { - "should": Array [ - Object { - "range": Object { - "visualize.created": Object { - "gt": undefined, - "gte": undefined, - "lt": 2012-01-01T07:00:00.000Z, - "lte": undefined, - }, - }, - }, - Object { - "range": Object { - "dashboard.created": Object { - "gt": undefined, - "gte": undefined, - "lt": 2012-01-01T07:00:00.000Z, - "lte": undefined, - }, - }, - }, - ], + "range": Object { + "updated_at": Object { + "gt": undefined, + "gte": undefined, + "lt": 2012-01-01T07:00:00.000Z, + "lte": undefined, + }, }, }, Object { @@ -157,55 +109,23 @@ Object { "must_not": Array [], "should": Array [ Object { - "bool": Object { - "should": Array [ - Object { - "range": Object { - "visualize.created": Object { - "gt": undefined, - "gte": 2018-03-02T07:00:00.000Z, - "lt": 2018-03-03T07:00:00.000Z, - "lte": undefined, - }, - }, - }, - Object { - "range": Object { - "dashboard.created": Object { - "gt": undefined, - "gte": 2018-03-02T07:00:00.000Z, - "lt": 2018-03-03T07:00:00.000Z, - "lte": undefined, - }, - }, - }, - ], + "range": Object { + "updated_at": Object { + "gt": undefined, + "gte": 2018-03-02T07:00:00.000Z, + "lt": 2018-03-03T07:00:00.000Z, + "lte": undefined, + }, }, }, Object { - "bool": Object { - "should": Array [ - Object { - "range": Object { - "visualize.created": Object { - "gt": undefined, - "gte": 2018-03-01T07:00:00.000Z, - "lt": 2018-03-02T07:00:00.000Z, - "lte": undefined, - }, - }, - }, - Object { - "range": Object { - "dashboard.created": Object { - "gt": undefined, - "gte": 2018-03-01T07:00:00.000Z, - "lt": 2018-03-02T07:00:00.000Z, - "lte": undefined, - }, - }, - }, - ], + "range": Object { + "updated_at": Object { + "gt": undefined, + "gte": 2018-03-01T07:00:00.000Z, + "lt": 2018-03-02T07:00:00.000Z, + "lte": undefined, + }, }, }, ], diff --git a/src/server/saved_objects/client/lib/search_dsl/experimental_filter/convert.js b/src/server/saved_objects/client/lib/search_dsl/experimental_filter/convert.js index 1312162f3445004..b922985ace9ee23 100644 --- a/src/server/saved_objects/client/lib/search_dsl/experimental_filter/convert.js +++ b/src/server/saved_objects/client/lib/search_dsl/experimental_filter/convert.js @@ -1,70 +1,71 @@ import { parseAndValidateFromApi } from './parse_and_validate_from_api'; -export function convertFilterToEsDsl(types, apiParam) { - return convertFilter(types, parseAndValidateFromApi(apiParam)); +function getExpandedFields(savedObjectTypes, rootAttributes, field) { + if (rootAttributes.includes(field)) { + return [field]; + } + + return savedObjectTypes.reduce((acc, t) => [ + ...acc, + `${t}.${field}` + ], []); } -function getFilterFields(types, field) { - switch (field) { - case 'type': - case 'updated_at': - return [field]; +export function convertFilterToEsDsl(savedObjectTypes, rootAttributes, apiParam) { + const rootFilter = parseAndValidateFromApi(apiParam); - default: - return types.reduce((acc, t) => [ - ...acc, - `${t}.${field}` - ], []); - } -} + function recursivelyConvert(filter) { + const fields = filter.field + ? getExpandedFields(savedObjectTypes, rootAttributes, filter.field) + : undefined; -function convertFilter(types, filter) { - switch (filter.type) { - case 'value': { - return { - multi_match: { - type: 'phrase', - query: filter.value, - fields: filter.field - ? getFilterFields(types, filter.field) - : undefined, - } - }; - } + switch (filter.type) { + case 'value': { + return { + multi_match: { + type: 'phrase', + query: filter.value, + fields, + } + }; + } - case 'range': { - const filters = getFilterFields(types, filter.field).map(field => ({ - range: { - [field]: { - gt: filter.gt, - gte: filter.gte, - lt: filter.lt, - lte: filter.lte, + case 'range': { + const filters = fields.map(field => ({ + range: { + [field]: { + gt: filter.gt, + gte: filter.gte, + lt: filter.lt, + lte: filter.lte, + } } + })); + + if (filters.length > 1) { + return { + bool: { + should: filters + } + }; } - })); - if (filters.length > 1) { + return filters[0]; + } + + case 'bool': return { bool: { - should: filters + must: filter.must.map(recursivelyConvert), + must_not: filter.must_not.map(recursivelyConvert), + should: filter.must_some.map(recursivelyConvert), } }; - } - return filters[0]; + default: + throw new Error(`unexpected filter.type "${filter.type}"`); } - - case 'bool': - return { - bool: { - must: filter.must.map(filter => convertFilter(types, filter)), - must_not: filter.must_not.map(filter => convertFilter(types, filter)), - should: filter.must_some.map(filter => convertFilter(types, filter)), - } - }; - - default: - throw new Error(`unexpected filter.type "${filter.type}"`); } + + return recursivelyConvert(rootFilter); } diff --git a/src/server/saved_objects/client/lib/search_dsl/experimental_filter/convert.test.js b/src/server/saved_objects/client/lib/search_dsl/experimental_filter/convert.test.js index c742addc6b8e212..88be0829c3f999b 100644 --- a/src/server/saved_objects/client/lib/search_dsl/experimental_filter/convert.test.js +++ b/src/server/saved_objects/client/lib/search_dsl/experimental_filter/convert.test.js @@ -2,16 +2,16 @@ import { convertFilterToEsDsl } from './convert'; describe('SavedObjectsClient/experimentalFilter', () => { it('properly converts complex example', () => { - expect(convertFilterToEsDsl(['visualize', 'dashboard'], { + expect(convertFilterToEsDsl(['visualize', 'dashboard'], ['type', 'updated_at'], { must: [ // numeric ranges { field: 'stars', gt: 3 }, { field: 'followers', lte: 5 }, // date ranges - { field: 'created', gte: '2018-03-02T00:00:00-07:00', lt: '2018-03-03T00:00:00-07:00' }, - { field: 'created', gte: '2018-02-25T00:00:00-07:00', lt: '2018-03-01T00:00:00-07:00' }, - { field: 'created', lt: '2012-01-01T00:00:00-07:00' }, + { field: 'updated_at', gte: '2018-03-02T00:00:00-07:00', lt: '2018-03-03T00:00:00-07:00' }, + { field: 'updated_at', gte: '2018-02-25T00:00:00-07:00', lt: '2018-03-01T00:00:00-07:00' }, + { field: 'updated_at', lt: '2012-01-01T00:00:00-07:00' }, // match, field not required { value: 'dashboard' }, @@ -21,9 +21,9 @@ describe('SavedObjectsClient/experimentalFilter', () => { { must_some: [ // today - { field: 'created', gte: '2018-03-02T00:00:00-07:00', lt: '2018-03-03T00:00:00-07:00' }, + { field: 'updated_at', gte: '2018-03-02T00:00:00-07:00', lt: '2018-03-03T00:00:00-07:00' }, // yesterday - { field: 'created', gte: '2018-03-01T00:00:00-07:00', lt: '2018-03-02T00:00:00-07:00' } + { field: 'updated_at', gte: '2018-03-01T00:00:00-07:00', lt: '2018-03-02T00:00:00-07:00' } ] } ], diff --git a/src/server/saved_objects/client/lib/search_dsl/query_params.js b/src/server/saved_objects/client/lib/search_dsl/query_params.js index e83256afbb788f6..06bd21855c74ae0 100644 --- a/src/server/saved_objects/client/lib/search_dsl/query_params.js +++ b/src/server/saved_objects/client/lib/search_dsl/query_params.js @@ -2,12 +2,13 @@ import { getRootProperties } from '../../../../mappings'; import { convertExperimentalFilterToEsDsl } from './experimental_filter'; /** - * Get the field params based on the types and searchFields + * Get the field params based on the searchFields and savedObjectTypes+rootAttributes from the mapping * @param {Array} searchFields - * @param {Array} types + * @param {Array} savedObjectTypes + * @param {Array} rootAttributes * @return {Object} */ -function getFieldsForTypes(searchFields, types) { +function getFieldsForTypes(searchFields, types, rootAttributes) { if (!searchFields || !searchFields.length) { return { all_fields: true @@ -17,11 +18,34 @@ function getFieldsForTypes(searchFields, types) { return { fields: searchFields.reduce((acc, field) => [ ...acc, - ...types.map(prefix => `${prefix}.${field}`) + ...rootAttributes.includes(field) + ? [field] + : types.map(prefix => `${prefix}.${field}`) ], []), }; } +function readMappings(mappings) { + // object types in the mappings are for saved object types + const savedObjectTypes = []; + + // non-object types are for shared/global attributes like updated_at and type + const rootAttributes = []; + + for (const [propName, propMapping] of Object.entries(getRootProperties(mappings))) { + if (propMapping.type === 'object' || propMapping.properties) { + savedObjectTypes.push(propName); + } else { + rootAttributes.push(propName); + } + } + + return { + savedObjectTypes, + rootAttributes, + }; +} + /** * Get the "query" related keys for the search body * @param {EsMapping} mapping mappings from Ui @@ -36,8 +60,11 @@ export function getQueryParams(mappings, type, search, searchFields, experimenta return {}; } + const { savedObjectTypes, rootAttributes } = readMappings(mappings); + const searchTypes = type ? [type] : savedObjectTypes; + const bool = {}; - const savedObjectTypes = type ? [type] : Object.keys(getRootProperties(mappings)); + if (type) { bool.filter = [ @@ -52,7 +79,8 @@ export function getQueryParams(mappings, type, search, searchFields, experimenta query: search, ...getFieldsForTypes( searchFields, - savedObjectTypes + searchTypes, + rootAttributes, ) } } @@ -61,7 +89,7 @@ export function getQueryParams(mappings, type, search, searchFields, experimenta if (experimentalFilter) { bool.must = (bool.must || []).concat( - convertExperimentalFilterToEsDsl(savedObjectTypes, experimentalFilter) + convertExperimentalFilterToEsDsl(savedObjectTypes, rootAttributes, experimentalFilter) ); }