diff --git a/server/src/entities/asset.entity.ts b/server/src/entities/asset.entity.ts index cc3a8bb1a0..64c038a689 100644 --- a/server/src/entities/asset.entity.ts +++ b/server/src/entities/asset.entity.ts @@ -90,30 +90,19 @@ export function withFiles(eb: ExpressionBuilder, type?: AssetFileT } export function withFacesAndPeople(eb: ExpressionBuilder, withDeletedFace?: boolean) { - return eb - .selectFrom('asset_faces') - .leftJoin('person', 'person.id', 'asset_faces.personId') - .whereRef('asset_faces.assetId', '=', 'assets.id') - .$if(!withDeletedFace, (qb) => qb.where('asset_faces.deletedAt', 'is', null)) - .select((eb) => - eb - .fn('jsonb_agg', [ - eb - .case() - .when('person.id', 'is not', null) - .then( - eb.fn('jsonb_insert', [ - eb.fn('to_jsonb', [eb.table('asset_faces')]), - sql`'{person}'::text[]`, - eb.fn('to_jsonb', [eb.table('person')]), - ]), - ) - .else(eb.fn('to_jsonb', [eb.table('asset_faces')])) - .end(), - ]) - .as('faces'), - ) - .as('faces'); + return jsonArrayFrom( + eb + .selectFrom('asset_faces') + .leftJoinLateral( + (eb) => + eb.selectFrom('person').selectAll('person').whereRef('asset_faces.personId', '=', 'person.id').as('person'), + (join) => join.onTrue(), + ) + .selectAll('asset_faces') + .select((eb) => eb.table('person').as('person')) + .whereRef('asset_faces.assetId', '=', 'assets.id') + .$if(!withDeletedFace, (qb) => qb.where('asset_faces.deletedAt', 'is', null)), + ).as('faces'); } export function hasPeople(qb: SelectQueryBuilder, personIds: string[]) { diff --git a/server/src/queries/asset.repository.sql b/server/src/queries/asset.repository.sql index fa89814b8b..cf17bb0276 100644 --- a/server/src/queries/asset.repository.sql +++ b/server/src/queries/asset.repository.sql @@ -87,22 +87,26 @@ select "assets".*, ( select - jsonb_agg( - case - when "person"."id" is not null then jsonb_insert( - to_jsonb("asset_faces"), - '{person}'::text[], - to_jsonb("person") - ) - else to_jsonb("asset_faces") - end - ) as "faces" + coalesce(json_agg(agg), '[]') from - "asset_faces" - left join "person" on "person"."id" = "asset_faces"."personId" - where - "asset_faces"."assetId" = "assets"."id" - and "asset_faces"."deletedAt" is null + ( + select + "asset_faces".*, + "person" as "person" + from + "asset_faces" + left join lateral ( + select + "person".* + from + "person" + where + "asset_faces"."personId" = "person"."id" + ) as "person" on true + where + "asset_faces"."assetId" = "assets"."id" + and "asset_faces"."deletedAt" is null + ) as agg ) as "faces", ( select