Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow passing a default operator to use on saved object client find operations #29339

Merged
2 changes: 2 additions & 0 deletions docs/api/saved-objects/find.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ Note: You cannot access this endpoint via the Console in Kibana.
(number) The page of objects to return
`search` (optional)::
(string) A {ref}/query-dsl-simple-query-string-query.html[simple_query_string] Elasticsearch query to filter the objects in the response
`search_operator` (optional)::
(string) The default operator to use for the `simple_query_string`
`search_fields` (optional)::
(array|string) The fields to perform the `simple_query_string` parsed query against
`fields` (optional)::
Expand Down
1 change: 1 addition & 0 deletions src/server/saved_objects/routes/find.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export const createFindRoute = (prereqs) => ({
page: Joi.number().min(0).default(1),
type: Joi.array().items(Joi.string()).single().required(),
search: Joi.string().allow('').optional(),
search_operator: Joi.string().allow('OR', 'AND').optional(),
mikecote marked this conversation as resolved.
Show resolved Hide resolved
search_fields: Joi.array().items(Joi.string()).single(),
sort_field: Joi.array().items(Joi.string()).single(),
fields: Joi.array().items(Joi.string()).single()
Expand Down
3 changes: 3 additions & 0 deletions src/server/saved_objects/service/lib/repository.js
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ export class SavedObjectsRepository {
* @param {object} [options={}]
* @property {(string|Array<string>)} [options.type]
* @property {string} [options.search]
* @property {string} [options.searchOperator]
* @property {Array<string>} [options.searchFields] - see Elasticsearch Simple Query String
* Query field argument for more information
* @property {integer} [options.page=1]
Expand All @@ -295,6 +296,7 @@ export class SavedObjectsRepository {
const {
type,
search,
searchOperator,
searchFields,
page = 1,
perPage = 20,
Expand Down Expand Up @@ -327,6 +329,7 @@ export class SavedObjectsRepository {
version: true,
...getSearchDsl(this._mappings, this._schema, {
search,
searchOperator,
searchFields,
type,
sortField,
Expand Down
3 changes: 2 additions & 1 deletion src/server/saved_objects/service/lib/repository.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -814,7 +814,7 @@ describe('SavedObjectsRepository', () => {
}
});

it('passes mappings, schema, search, searchFields, type, sortField, and sortOrder to getSearchDsl', async () => {
it('passes mappings, schema, search, searchOperator, searchFields, type, sortField, and sortOrder to getSearchDsl', async () => {
callAdminCluster.returns(namespacedSearchResults);
const relevantOpts = {
namespace: 'foo-namespace',
Expand All @@ -823,6 +823,7 @@ describe('SavedObjectsRepository', () => {
type: 'bar',
sortField: 'name',
sortOrder: 'desc',
searchOperator: 'AND',
};

await savedObjectsRepository.find(relevantOpts);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,10 @@ function getClauseForType(schema, namespace, type) {
* @param {(string|Array<string>)} type
* @param {String} search
* @param {Array<string>} searchFields
* @param {String} searchOperator
* @return {Object}
*/
export function getQueryParams(mappings, schema, namespace, type, search, searchFields) {
export function getQueryParams(mappings, schema, namespace, type, search, searchFields, searchOperator = 'OR') {
mikecote marked this conversation as resolved.
Show resolved Hide resolved
const types = getTypes(mappings, type);
const bool = {
filter: [{
Expand All @@ -116,6 +117,7 @@ export function getQueryParams(mappings, schema, namespace, type, search, search
{
simple_query_string: {
query: search,
default_operator: searchOperator,
...getFieldsForTypes(
searchFields,
types
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ describe('searchDsl/queryParams', () => {
must: [
{
simple_query_string: {
default_operator: 'OR',
query: 'us*',
all_fields: true
}
Expand Down Expand Up @@ -266,6 +267,7 @@ describe('searchDsl/queryParams', () => {
must: [
{
simple_query_string: {
default_operator: 'OR',
query: 'us*',
all_fields: true
}
Expand Down Expand Up @@ -295,6 +297,7 @@ describe('searchDsl/queryParams', () => {
must: [
{
simple_query_string: {
default_operator: 'OR',
query: 'us*',
all_fields: true
}
Expand Down Expand Up @@ -324,6 +327,7 @@ describe('searchDsl/queryParams', () => {
must: [
{
simple_query_string: {
default_operator: 'OR',
query: 'us*',
all_fields: true
}
Expand Down Expand Up @@ -355,6 +359,7 @@ describe('searchDsl/queryParams', () => {
{
simple_query_string: {
query: 'y*',
default_operator: 'OR',
fields: [
'pending.title',
'saved.title',
Expand Down Expand Up @@ -386,6 +391,7 @@ describe('searchDsl/queryParams', () => {
{
simple_query_string: {
query: 'y*',
default_operator: 'OR',
fields: [
'pending.title^3',
'saved.title^3',
Expand Down Expand Up @@ -417,6 +423,7 @@ describe('searchDsl/queryParams', () => {
{
simple_query_string: {
query: 'y*',
default_operator: 'OR',
fields: [
'pending.title',
'saved.title',
Expand Down Expand Up @@ -454,6 +461,7 @@ describe('searchDsl/queryParams', () => {
{
simple_query_string: {
query: 'y*',
default_operator: 'OR',
fields: [
'pending.title',
'saved.title',
Expand Down Expand Up @@ -485,6 +493,7 @@ describe('searchDsl/queryParams', () => {
{
simple_query_string: {
query: 'y*',
default_operator: 'OR',
fields: [
'pending.title^3',
'saved.title^3',
Expand Down Expand Up @@ -516,6 +525,7 @@ describe('searchDsl/queryParams', () => {
{
simple_query_string: {
query: 'y*',
default_operator: 'OR',
fields: [
'pending.title',
'saved.title',
Expand Down Expand Up @@ -552,6 +562,7 @@ describe('searchDsl/queryParams', () => {
{
simple_query_string: {
query: 'y*',
default_operator: 'OR',
fields: [
'saved.title',
'global.title',
Expand Down Expand Up @@ -581,6 +592,7 @@ describe('searchDsl/queryParams', () => {
{
simple_query_string: {
query: 'y*',
default_operator: 'OR',
fields: [
'saved.title^3',
'global.title^3',
Expand Down Expand Up @@ -610,6 +622,7 @@ describe('searchDsl/queryParams', () => {
{
simple_query_string: {
query: 'y*',
default_operator: 'OR',
fields: [
'saved.title',
'global.title',
Expand Down Expand Up @@ -644,6 +657,7 @@ describe('searchDsl/queryParams', () => {
{
simple_query_string: {
query: 'y*',
default_operator: 'OR',
fields: [
'saved.title',
'global.title',
Expand Down Expand Up @@ -673,6 +687,7 @@ describe('searchDsl/queryParams', () => {
{
simple_query_string: {
query: 'y*',
default_operator: 'OR',
fields: [
'saved.title^3',
'global.title^3',
Expand Down Expand Up @@ -702,6 +717,7 @@ describe('searchDsl/queryParams', () => {
{
simple_query_string: {
query: 'y*',
default_operator: 'OR',
fields: [
'saved.title',
'global.title',
Expand All @@ -716,4 +732,68 @@ describe('searchDsl/queryParams', () => {
});
});
});

describe('type (plural, namespaced and global), search, searchOperator', () => {
it('supports searchOperator', () => {
expect(getQueryParams(MAPPINGS, SCHEMA, 'foo-namespace', ['saved', 'global'], 'foo', null, 'AND'))
.toEqual({
query: {
bool: {
filter: [
{
bool: {
minimum_should_match: 1,
should: [
{
bool: {
must: [
{
term: {
type: 'saved',
},
},
{
term: {
namespace: 'foo-namespace',
},
},
],
},
},
{
bool: {
must: [
{
term: {
type: 'global',
},
},
],
must_not: [
{
exists: {
field: 'namespace',
},
},
],
},
},
],
},
},
],
must: [
{
simple_query_string: {
all_fields: true,
default_operator: 'AND',
query: 'foo',
},
},
],
},
},
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export function getSearchDsl(mappings, schema, options = {}) {
const {
type,
search,
searchOperator,
searchFields,
sortField,
sortOrder,
Expand All @@ -41,7 +42,7 @@ export function getSearchDsl(mappings, schema, options = {}) {
}

return {
...getQueryParams(mappings, schema, namespace, type, search, searchFields),
...getQueryParams(mappings, schema, namespace, type, search, searchFields, searchOperator),
...getSortingParams(mappings, type, sortField, sortOrder),
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ describe('getSearchDsl', () => {
type: 'foo',
search: 'bar',
searchFields: ['baz'],
searchOperator: 'AND',
};

getSearchDsl(mappings, schema, opts);
Expand All @@ -67,6 +68,7 @@ describe('getSearchDsl', () => {
opts.type,
opts.search,
opts.searchFields,
opts.searchOperator,
);
});

Expand Down
1 change: 1 addition & 0 deletions src/server/saved_objects/service/saved_objects_client.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ export class SavedObjectsClient {
* @param {object} [options={}]
* @property {(string|Array<string>)} [options.type]
* @property {string} [options.search]
* @property {string} [options.searchOperator]
* @property {Array<string>} [options.searchFields] - see Elasticsearch Simple Query String
* Query field argument for more information
* @property {integer} [options.page=1]
Expand Down
1 change: 1 addition & 0 deletions src/ui/public/courier/saved_object/saved_object_loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ export class SavedObjectLoader {
perPage: size,
page: 1,
searchFields: ['title^3', 'description'],
searchOperator: 'AND',
fields,
}).then((resp) => {
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ class SavedObjectFinderUI extends React.Component {
search: filter ? `${filter}*` : undefined,
page: 1,
perPage: chrome.getUiSettingsClient().get('savedObjects:listingLimit'),
searchFields: ['title^3', 'description']
searchFields: ['title^3', 'description'],
searchOperator: 'AND',
});

if (this.props.savedObjectType === 'visualization'
Expand Down
1 change: 1 addition & 0 deletions src/ui/public/saved_objects/saved_objects_client.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ export class SavedObjectsClient {
* @param {object} [options={}]
* @property {string} options.type
* @property {string} options.search
* @property {string} options.searchOperator
* @property {string} options.searchFields - see Elasticsearch Simple Query String
* Query field argument for more information
* @property {integer} [options.page=1]
Expand Down
6 changes: 6 additions & 0 deletions test/functional/apps/dashboard/_dashboard_listing.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,12 @@ export default function ({ getService, getPageObjects }) {
const countOfDashboards = await PageObjects.dashboard.getCountOfDashboardsInListingTable();
expect(countOfDashboards).to.equal(1);
});

it('is using AND operator', async function () {
await PageObjects.dashboard.searchForDashboardWithName('three words');
const countOfDashboards = await PageObjects.dashboard.getCountOfDashboardsInListingTable();
expect(countOfDashboards).to.equal(0);
});
});

describe('search by title', function () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ export class SpacesSavedObjectsClient implements SavedObjectsClient {
* @param {object} [options={}]
* @property {(string|Array<string>)} [options.type]
* @property {string} [options.search]
* @property {string} [options.searchOperator]
* @property {Array<string>} [options.searchFields] - see Elasticsearch Simple Query String
* Query field argument for more information
* @property {integer} [options.page=1]
Expand Down