From 0c1f828084915704e9774ff936c19d31a8b321a2 Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet Date: Tue, 17 Oct 2023 10:21:01 +0200 Subject: [PATCH] [SOM] use aggregation for type counts (#168918) ## Summary Use an aggregation for type counts in SO management instead of scrolling through all the documents. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../server/lib/get_saved_objects_counts.ts | 45 +++++++++++++++++++ .../server/lib/index.ts | 1 + .../server/routes/scroll_count.ts | 27 +++++------ .../saved_objects_management/tsconfig.json | 1 + 4 files changed, 57 insertions(+), 17 deletions(-) create mode 100644 src/plugins/saved_objects_management/server/lib/get_saved_objects_counts.ts diff --git a/src/plugins/saved_objects_management/server/lib/get_saved_objects_counts.ts b/src/plugins/saved_objects_management/server/lib/get_saved_objects_counts.ts new file mode 100644 index 0000000000000..266c79e99c0c4 --- /dev/null +++ b/src/plugins/saved_objects_management/server/lib/get_saved_objects_counts.ts @@ -0,0 +1,45 @@ +/* + * 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 { estypes } from '@elastic/elasticsearch'; +import type { SavedObjectsFindOptions } from '@kbn/core-saved-objects-api-server'; +import type { SavedObjectsClientContract } from '@kbn/core/server'; + +export const getSavedObjectCounts = async ({ + types, + options, + client, +}: { + types: string[]; + options: SavedObjectsFindOptions; + client: SavedObjectsClientContract; +}): Promise> => { + const body = await client.find({ + ...options, + type: types, + perPage: 0, + aggs: { + types: { + terms: { + field: 'type', + size: types.length, + }, + }, + }, + }); + + const buckets = + (body.aggregations?.types?.buckets as estypes.AggregationsStringTermsBucketKeys[]) || []; + + const counts = buckets.reduce((memo, bucket) => { + memo[bucket.key] = bucket.doc_count; + return memo; + }, {} as Record); + + return counts; +}; diff --git a/src/plugins/saved_objects_management/server/lib/index.ts b/src/plugins/saved_objects_management/server/lib/index.ts index 0038152891b7c..0cd4768934dae 100644 --- a/src/plugins/saved_objects_management/server/lib/index.ts +++ b/src/plugins/saved_objects_management/server/lib/index.ts @@ -9,3 +9,4 @@ export { toSavedObjectWithMeta } from './to_saved_object_with_meta'; export { injectMetaAttributes } from './inject_meta_attributes'; export { findRelationships } from './find_relationships'; +export { getSavedObjectCounts } from './get_saved_objects_counts'; diff --git a/src/plugins/saved_objects_management/server/routes/scroll_count.ts b/src/plugins/saved_objects_management/server/routes/scroll_count.ts index d5649572ccbed..5ad90dae72c6a 100644 --- a/src/plugins/saved_objects_management/server/routes/scroll_count.ts +++ b/src/plugins/saved_objects_management/server/routes/scroll_count.ts @@ -10,6 +10,7 @@ import { schema } from '@kbn/config-schema'; import type { IRouter, SavedObjectsCreatePointInTimeFinderOptions } from '@kbn/core/server'; import { chain } from 'lodash'; import type { v1 } from '../../common'; +import { getSavedObjectCounts } from '../lib'; export const registerScrollForCountRoute = (router: IRouter) => { router.post( @@ -44,27 +45,19 @@ export const registerScrollForCountRoute = (router: IRouter) => { const client = getClient({ includedHiddenTypes }); const findOptions: SavedObjectsCreatePointInTimeFinderOptions = { type: typesToInclude, - perPage: 500, + ...(searchString ? { search: `${searchString}*`, searchFields: ['title'] } : {}), + ...(references ? { hasReference: references, hasReferenceOperator: 'OR' } : {}), }; - if (searchString) { - findOptions.search = `${searchString}*`; - findOptions.searchFields = ['title']; - } - if (references) { - findOptions.hasReference = references; - findOptions.hasReferenceOperator = 'OR'; - } + + const rawCounts = await getSavedObjectCounts({ + types: typesToInclude, + client, + options: findOptions, + }); const counts: Record = {}; for (const type of typesToInclude) { - counts[type] = 0; - } - - const finder = client.createPointInTimeFinder(findOptions); - for await (const { saved_objects: savedObjects } of finder.find()) { - for (const { type } of savedObjects) { - counts[type]++; - } + counts[type] = rawCounts[type] ?? 0; } const body: v1.ScrollCountResponseHTTP = counts; diff --git a/src/plugins/saved_objects_management/tsconfig.json b/src/plugins/saved_objects_management/tsconfig.json index 4b832a1616a85..72eb9c29b30c8 100644 --- a/src/plugins/saved_objects_management/tsconfig.json +++ b/src/plugins/saved_objects_management/tsconfig.json @@ -28,6 +28,7 @@ "@kbn/shared-ux-router", "@kbn/core-ui-settings-browser-mocks", "@kbn/core-ui-settings-browser", + "@kbn/core-saved-objects-api-server", ], "exclude": [ "target/**/*",