feat: add searching by tags (#15395)

* feat: add searching by tags

* fix: fix merge

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
This commit is contained in:
David Wolff
2025-01-31 22:37:22 +01:00
committed by GitHub
parent 221e197633
commit 9ac95d6845
11 changed files with 187 additions and 5 deletions

View File

@@ -111,6 +111,9 @@ class BaseSearchDto {
@ValidateUUID({ each: true, optional: true })
personIds?: string[];
@ValidateUUID({ each: true, optional: true })
tagIds?: string[];
}
export class RandomSearchDto extends BaseSearchDto {

View File

@@ -252,6 +252,21 @@ export function hasPeople<O>(qb: SelectQueryBuilder<DB, 'assets', O>, personIds:
);
}
export function hasTags<O>(qb: SelectQueryBuilder<DB, 'assets', O>, tagIds: string[]) {
return qb.innerJoin(
(eb) =>
eb
.selectFrom('tag_asset')
.select('assetsId')
.innerJoin('tags_closure', 'tag_asset.tagsId', 'tags_closure.id_descendant')
.where('tags_closure.id_ancestor', '=', anyUuid(tagIds))
.groupBy('assetsId')
.having((eb) => eb.fn.count('tags_closure.id_ancestor').distinct(), '>=', tagIds.length)
.as('has_tags'),
(join) => join.onRef('has_tags.assetsId', '=', 'assets.id'),
);
}
export function withOwner(eb: ExpressionBuilder<DB, 'assets'>) {
return jsonObjectFrom(eb.selectFrom('users').selectAll().whereRef('users.id', '=', 'assets.ownerId')).as('owner');
}
@@ -326,6 +341,7 @@ export function searchAssetBuilder(kysely: Kysely<DB>, options: AssetSearchBuild
.withPlugin(joinDeduplicationPlugin)
.selectFrom('assets')
.selectAll('assets')
.$if(!!options.tagIds && options.tagIds.length > 0, (qb) => hasTags(qb, options.tagIds!))
.$if(!!options.personIds && options.personIds.length > 0, (qb) => hasPeople(qb, options.personIds!))
.$if(!!options.createdBefore, (qb) => qb.where('assets.createdAt', '<=', options.createdBefore!))
.$if(!!options.createdAfter, (qb) => qb.where('assets.createdAt', '>=', options.createdAfter!))

View File

@@ -112,6 +112,10 @@ export interface SearchPeopleOptions {
personIds?: string[];
}
export interface SearchTagOptions {
tagIds?: string[];
}
export interface SearchOrderOptions {
orderDirection?: 'asc' | 'desc';
}
@@ -128,7 +132,8 @@ type BaseAssetSearchOptions = SearchDateOptions &
SearchPathOptions &
SearchStatusOptions &
SearchUserIdOptions &
SearchPeopleOptions;
SearchPeopleOptions &
SearchTagOptions;
export type AssetSearchOptions = BaseAssetSearchOptions & SearchRelationOptions;
@@ -142,7 +147,8 @@ export type SmartSearchOptions = SearchDateOptions &
SearchOneToOneRelationOptions &
SearchStatusOptions &
SearchUserIdOptions &
SearchPeopleOptions;
SearchPeopleOptions &
SearchTagOptions;
export interface FaceEmbeddingSearch extends SearchEmbeddingOptions {
hasPerson?: boolean;