diff --git a/server/src/queries/search.repository.sql b/server/src/queries/search.repository.sql index ef5fbe09be..099b7f4ee2 100644 --- a/server/src/queries/search.repository.sql +++ b/server/src/queries/search.repository.sql @@ -254,6 +254,7 @@ where and "visibility" = $2 and "deletedAt" is null and "state" is not null + and "state" != $3 -- SearchRepository.getCities select distinct @@ -266,6 +267,7 @@ where and "visibility" = $2 and "deletedAt" is null and "city" is not null + and "city" != $3 -- SearchRepository.getCameraMakes select distinct @@ -278,6 +280,7 @@ where and "visibility" = $2 and "deletedAt" is null and "make" is not null + and "make" != $3 -- SearchRepository.getCameraModels select distinct @@ -290,6 +293,7 @@ where and "visibility" = $2 and "deletedAt" is null and "model" is not null + and "model" != $3 -- SearchRepository.getCameraLensModels select distinct @@ -302,3 +306,4 @@ where and "visibility" = $2 and "deletedAt" is null and "lensModel" is not null + and "lensModel" != $3 diff --git a/server/src/repositories/search.repository.ts b/server/src/repositories/search.repository.ts index 13ac254654..ba72a70fdb 100644 --- a/server/src/repositories/search.repository.ts +++ b/server/src/repositories/search.repository.ts @@ -502,10 +502,7 @@ export class SearchRepository { return res.map((row) => row.lensModel!); } - private getExifField( - field: K, - userIds: string[], - ) { + private getExifField(field: 'city' | 'state' | 'country' | 'make' | 'model' | 'lensModel', userIds: string[]) { return this.db .selectFrom('asset_exif') .select(field) @@ -514,6 +511,7 @@ export class SearchRepository { .where('ownerId', '=', anyUuid(userIds)) .where('visibility', '=', AssetVisibility.Timeline) .where('deletedAt', 'is', null) - .where(field, 'is not', null); + .where(field, 'is not', null) + .where(field, '!=', ''); } } diff --git a/server/test/medium/specs/services/search.service.spec.ts b/server/test/medium/specs/services/search.service.spec.ts index c20b64ca7c..18e03b2e48 100644 --- a/server/test/medium/specs/services/search.service.spec.ts +++ b/server/test/medium/specs/services/search.service.spec.ts @@ -1,4 +1,5 @@ import { Kysely } from 'kysely'; +import { SearchSuggestionType } from 'src/dtos/search.dto'; import { AccessRepository } from 'src/repositories/access.repository'; import { AssetRepository } from 'src/repositories/asset.repository'; import { DatabaseRepository } from 'src/repositories/database.repository'; @@ -108,4 +109,25 @@ describe(SearchService.name, () => { expect(response.assets.items[0].id).toBe(unstackedAsset.id); }); }); + + describe('getSearchSuggestions', () => { + it('should filter out empty search suggestions', async () => { + const { sut, ctx } = setup(); + const { user } = await ctx.newUser(); + + const { asset } = await ctx.newAsset({ ownerId: user.id }); + await ctx.newExif({ assetId: asset.id, make: 'Canon' }); + + const { asset: assetWithEmptyMake } = await ctx.newAsset({ ownerId: user.id }); + await ctx.newExif({ assetId: assetWithEmptyMake.id, make: '' }); + + const auth = factory.auth({ user: { id: user.id } }); + const suggestions = await sut.getSearchSuggestions(auth, { + type: SearchSuggestionType.CAMERA_MAKE, + includeNull: true, + }); + + expect(suggestions).toEqual(['Canon', null]); + }); + }); });