diff --git a/src/adverts/repository/category-search/convert-filter-to-category-matching-filter.ts b/src/adverts/repository/category-search/convert-filter-to-category-matching-filter.ts index 0a43cde..806e2fa 100644 --- a/src/adverts/repository/category-search/convert-filter-to-category-matching-filter.ts +++ b/src/adverts/repository/category-search/convert-filter-to-category-matching-filter.ts @@ -64,6 +64,8 @@ export const convertFilterToCategoryMatchingFilter = async ( return { ...filter, + pipelineCategoryIds: allCategoryIds, + /* pipelineOr: [ ...(filter.pipelineOr || []), { @@ -74,5 +76,6 @@ export const convertFilterToCategoryMatchingFilter = async ( }, }, ], + */ } } diff --git a/src/adverts/repository/category-search/convert.spec.ts b/src/adverts/repository/category-search/convert.spec.ts index 977b36d..4cbf05b 100644 --- a/src/adverts/repository/category-search/convert.spec.ts +++ b/src/adverts/repository/category-search/convert.spec.ts @@ -32,15 +32,7 @@ describe('convertFilterToCategoryMatchingFilter', () => { }) ).toMatchObject({ search: 'I can haz cheezburger', - pipelineOr: [ - { - fields: { - category: { - in: ['c1'], - }, - }, - }, - ], + pipelineCategoryIds: ['c1'], }) }) }) diff --git a/src/adverts/repository/mongo/filters/map-search.ts b/src/adverts/repository/mongo/filters/map-search.ts index d2b78bc..b996af1 100644 --- a/src/adverts/repository/mongo/filters/map-search.ts +++ b/src/adverts/repository/mongo/filters/map-search.ts @@ -1,17 +1,29 @@ import type { Filter } from 'mongodb' import type { MongoAdvert } from '../types' -import { escapeRegExp } from './filter-utils' +import { combineOr, escapeRegExp } from './filter-utils' -export const mapSearch = ( - search?: string -): Filter | null | undefined => - [search] - .map(s => (s || '').trim()) - .filter(s => s) - .map(s => ({ - $or: [ +const srch = (s: string) => + s + ? [ { 'advert.title': { $regex: escapeRegExp(s), $options: 'i' } }, { 'advert.description': { $regex: escapeRegExp(s), $options: 'i' } }, { 'advert.reference': { $regex: escapeRegExp(s), $options: 'i' } }, - ], - }))[0] || null + ] + : [] + +const cat = (categoryIds: string[]) => + categoryIds.length + ? [ + { + 'advert.category': { + $in: categoryIds, + }, + }, + ] + : [] + +export const mapSearch = ( + search?: string, + categoryIds?: string[] +): Filter | null | undefined => + combineOr(...[...srch((search || '').trim()), ...cat(categoryIds || [])]) diff --git a/src/adverts/repository/mongo/mappers.ts b/src/adverts/repository/mongo/mappers.ts index e6ab1ba..35bbf75 100644 --- a/src/adverts/repository/mongo/mappers.ts +++ b/src/adverts/repository/mongo/mappers.ts @@ -58,7 +58,10 @@ export const mapAdvertFilterInputToMongoQuery = ( ): Filter => combineAnd( combineOr( - combineAnd(mapSearch(filter?.search), mapFields(filter?.fields)), + combineAnd( + mapSearch(filter?.search, filter?.pipelineCategoryIds), + mapFields(filter?.fields) + ), ...(filter?.pipelineOr?.map(({ fields }) => mapFields(fields)) || []) ), mapRestrictions(user, filter?.restrictions) diff --git a/src/adverts/types.ts b/src/adverts/types.ts index 146dba6..cc606e9 100644 --- a/src/adverts/types.ts +++ b/src/adverts/types.ts @@ -205,6 +205,7 @@ export interface AdvertFilterInput { paging?: AdvertPagingInput // decorators/pipelines can attach additional criterias + pipelineCategoryIds?: string[] pipelineOr?: { fields: AdvertFieldsFilterInput }[]