diff --git a/packages/api/src/elastic/pages.ts b/packages/api/src/elastic/pages.ts index b65af5c41..1c4a9d482 100644 --- a/packages/api/src/elastic/pages.ts +++ b/packages/api/src/elastic/pages.ts @@ -179,6 +179,14 @@ const appendMatchFilters = (body: SearchBody, filters: FieldFilter[]): void => { }) } +const appendIdsFilter = (body: SearchBody, ids: string[]): void => { + body.query.bool.must.push({ + terms: { + _id: ids, + }, + }) +} + export const createPage = async ( page: Page, ctx: PageContext @@ -359,6 +367,7 @@ export const searchPages = async ( dateFilters, termFilters, matchFilters, + ids, } = args // default order is descending const sortOrder = sort?.order || SortOrder.DESCENDING @@ -430,6 +439,9 @@ export const searchPages = async ( if (matchFilters) { appendMatchFilters(body, matchFilters) } + if (ids && ids.length > 0) { + appendIdsFilter(body, ids) + } if (!args.includePending) { body.query.bool.must_not.push({ diff --git a/packages/api/src/elastic/types.ts b/packages/api/src/elastic/types.ts index 2cc85d417..46b9722f7 100644 --- a/packages/api/src/elastic/types.ts +++ b/packages/api/src/elastic/types.ts @@ -56,6 +56,11 @@ export interface SearchBody { [K: string]: string } } + | { + terms: { + [K: string]: string[] + } + } )[] should: { multi_match: { @@ -278,4 +283,5 @@ export interface PageSearchArgs { matchFilters?: FieldFilter[] includePending?: boolean | null includeDeleted?: boolean + ids?: string[] } diff --git a/packages/api/src/utils/search.ts b/packages/api/src/utils/search.ts index c0244926d..da9a157a6 100644 --- a/packages/api/src/utils/search.ts +++ b/packages/api/src/utils/search.ts @@ -34,6 +34,7 @@ export interface SearchFilter { dateFilters: DateFilter[] termFilters: FieldFilter[] matchFilters: FieldFilter[] + ids: string[] } export enum LabelFilterType { @@ -245,6 +246,14 @@ const parseFieldFilter = ( } } +const parseIds = (field: string, str?: string): string[] | undefined => { + if (str === undefined) { + return undefined + } + + return str.split(',') +} + export const parseSearchQuery = (query: string | undefined): SearchFilter => { const searchQuery = query ? query.replace(/\W\s":/g, '') : undefined const result: SearchFilter = { @@ -256,6 +265,7 @@ export const parseSearchQuery = (query: string | undefined): SearchFilter => { dateFilters: [], termFilters: [], matchFilters: [], + ids: [], } if (!searchQuery) { @@ -268,6 +278,7 @@ export const parseSearchQuery = (query: string | undefined): SearchFilter => { dateFilters: [], termFilters: [], matchFilters: [], + ids: [], } } @@ -288,6 +299,7 @@ export const parseSearchQuery = (query: string | undefined): SearchFilter => { 'description', 'content', 'updated', + 'includes', ], tokenize: true, }) @@ -364,6 +376,11 @@ export const parseSearchQuery = (query: string | undefined): SearchFilter => { fieldFilter && result.matchFilters.push(fieldFilter) break } + case 'includes': { + const ids = parseIds(keyword.keyword, keyword.value) + ids && result.ids.push(...ids) + break + } } } }