fix: people page search (#32108)

fix: people page search (#32094)

(cherry picked from commit 549a76cd35ec9f63a76174992de50095192afa11)

Co-authored-by: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com>
This commit is contained in:
immich-push-o-matic[bot]
2026-10-05 16:23:02 +00:00
committed by GitHub
co-authored by Daniel Dietzler
parent 983177d570
commit 81de979a35
8 changed files with 89 additions and 64 deletions
+1
View File
@@ -69,6 +69,7 @@ const PersonSearchSchema = z
sharedWithId: z.uuid().optional().describe('Only include people to which the user was given access'),
isFavorite: stringToBool.optional().describe('Filter by favorite status'),
isHidden: stringToBool.optional().describe('Filter by hidden status'),
name: z.string().optional().describe('Filter by person name'),
})
.meta({ id: 'PersonSearchDto' });
+12
View File
@@ -147,6 +147,11 @@ limit
3
-- PersonRepository.getAllForUser
with
"similarity_threshold" as (
select
set_config('pg_trgm.word_similarity_threshold', '0.5', true) as "thresh"
)
select
(
select
@@ -234,6 +239,7 @@ select
) as agg
) as "sharedWith"
from
"similarity_threshold",
"person_group"
inner join "person" as "owned" on "owned"."personGroupId" = "person_group"."id"
and "owned"."ownerId" = $6
@@ -894,6 +900,11 @@ where
)
-- PersonRepository.getNumberOfPeople
with
"similarity_threshold" as (
select
set_config('pg_trgm.word_similarity_threshold', '0.5', true) as "thresh"
)
select
coalesce(count(*), 0) as "total",
coalesce(
@@ -904,6 +915,7 @@ select
0
) as "hidden"
from
"similarity_threshold",
"person_group"
left join "person" as "owned" on "owned"."personGroupId" = "person_group"."id"
and "owned"."ownerId" = $2
+21 -4
View File
@@ -39,6 +39,7 @@ export interface PersonFilterOptions {
sharedWithId?: string;
isFavorite?: boolean;
isHidden?: boolean;
name?: string;
}
export interface PersonSearchOptions extends PersonFilterOptions {
@@ -172,8 +173,13 @@ const withOtherPeopleForPerson = (userId: string) => {
};
const withFilters = (userId: string, options: PersonFilterOptions = {}) => {
const { sharedById, sharedWithId, isFavorite, isHidden } = options;
return (eb: ExpressionBuilder<DB & { owned: DB['person'] }, 'person_group' | 'owned'>) => {
const { sharedById, sharedWithId, isFavorite, isHidden, name } = options;
return (
eb: ExpressionBuilder<
DB & { owned: DB['person']; similarity_threshold: unknown },
'person_group' | 'owned' | 'similarity_threshold'
>,
) => {
const filters: Expression<SqlBool>[] = [];
if (sharedById || sharedWithId) {
@@ -200,6 +206,10 @@ const withFilters = (userId: string, options: PersonFilterOptions = {}) => {
filters.push(eb('owned.isHidden', '=', isHidden));
}
if (name !== undefined) {
filters.push(sql`f_unaccent("owned"."name") %> f_unaccent(${name})`);
}
return eb.and(filters);
};
};
@@ -429,7 +439,10 @@ export class PersonRepository {
@GenerateSql({ params: [{ take: 1, skip: 0 }, DummyValue.UUID] })
async getAllForUser(pagination: PaginationOptions, userId: string, options?: PersonSearchOptions) {
const items = await this.db
.selectFrom('person_group')
.with('similarity_threshold', (db) =>
db.selectNoFrom(sql`set_config('pg_trgm.word_similarity_threshold', '0.5', true)`.as('thresh')),
)
.selectFrom(['similarity_threshold', 'person_group'])
.innerJoin('person as owned', (join) =>
join.onRef('owned.personGroupId', '=', 'person_group.id').on('owned.ownerId', '=', userId),
)
@@ -502,6 +515,7 @@ export class PersonRepository {
// an explicit isHidden filter takes precedence over withHidden
.$if(!options?.withHidden && options?.isHidden === undefined, (qb) => qb.where('owned.isHidden', '=', false))
.where(withFilters(userId, options))
.$if(!!options?.name, (qb) => qb.orderBy(sql`f_unaccent("owned"."name") <->>> f_unaccent(${options!.name!})`))
.offset(pagination.skip ?? 0)
.limit(pagination.take + 1)
.execute();
@@ -726,7 +740,10 @@ export class PersonRepository {
getNumberOfPeople(userId: string, options?: PersonFilterOptions) {
const zero = sql.lit(0);
return this.db
.selectFrom('person_group')
.with('similarity_threshold', (db) =>
db.selectNoFrom(sql`set_config('pg_trgm.word_similarity_threshold', '0.5', true)`.as('thresh')),
)
.selectFrom(['similarity_threshold', 'person_group'])
.leftJoin('person as owned', (join) =>
join.onRef('owned.personGroupId', '=', 'person_group.id').on('owned.ownerId', '=', userId),
)