diff --git a/server/src/queries/asset.repository.sql b/server/src/queries/asset.repository.sql index 02ae5e7806..5fbc582107 100644 --- a/server/src/queries/asset.repository.sql +++ b/server/src/queries/asset.repository.sql @@ -236,12 +236,12 @@ limit with "assets" as ( select - date_trunc($1, "localDateTime" at time zone 'UTC') at time zone 'UTC' as "timeBucket" + date_trunc('MONTH', "localDateTime" at time zone 'UTC') at time zone 'UTC' as "timeBucket" from "assets" where "assets"."deletedAt" is null - and "assets"."isVisible" = $2 + and "assets"."isVisible" = $1 ) select "timeBucket", @@ -254,53 +254,95 @@ order by "timeBucket" desc -- AssetRepository.getTimeBucket -select - "assets"."id" as "id", - "assets"."ownerId", - "assets"."status", - "deletedAt", - "type", - "duration", - "isFavorite", - "isArchived", - "thumbhash", - "localDateTime", - "livePhotoVideoId", - "exif"."exifImageHeight" as "height", - "exifImageWidth" as "width", - "exif"."orientation", - "exif"."projectionType", - "exif"."city" as "city", - "exif"."country" as "country", - to_json("localDateTime" at time zone 'UTC') #>> '{}' as "localDateTime", - to_json("stacked_assets") as "stack" -from - "assets" - left join "exif" on "assets"."id" = "exif"."assetId" - left join "asset_stack" on "asset_stack"."id" = "assets"."stackId" - left join lateral ( +with + "cte" as ( select - "asset_stack".*, - count("stacked") as "assetCount" + "assets"."duration", + "assets"."id", + assets."isArchived"::int as "isArchived", + assets."isFavorite"::int as "isFavorite", + (assets.type = 'IMAGE')::int as "isImage", + (assets."deletedAt" is null)::int as "isTrashed", + (assets.type = 'VIDEO')::int as "isVideo", + "assets"."livePhotoVideoId", + "assets"."localDateTime", + "assets"."ownerId", + "assets"."status", + encode("assets"."thumbhash", 'base64') as "thumbhash", + "exif"."city", + "exif"."country", + "exif"."projectionType", + coalesce( + case + when exif."exifImageHeight" = 0 + or exif."exifImageWidth" = 0 then 1 + when "exif"."orientation" in ('5', '6', '7', '8', '-90', '90') then round( + exif."exifImageHeight"::numeric / exif."exifImageWidth"::numeric, + 3 + ) + else round( + exif."exifImageWidth"::numeric / exif."exifImageHeight"::numeric, + 3 + ) + end, + 1 + ) as "ratio", + "stack" from - "assets" as "stacked" + "assets" + inner join "exif" on "assets"."id" = "exif"."assetId" + left join lateral ( + select + json_build_array(stacked."stackId", count('stacked')) as "stack" + from + "assets" as "stacked" + where + "stacked"."stackId" = "assets"."stackId" + and "stacked"."deletedAt" is null + and "stacked"."isArchived" = $1 + group by + "stacked"."stackId" + ) as "stacked_assets" on true where - "stacked"."stackId" = "asset_stack"."id" - and "stacked"."deletedAt" is null - and "stacked"."isArchived" = $1 - group by - "asset_stack"."id" - ) as "stacked_assets" on "asset_stack"."id" is not null -where - ( - "asset_stack"."primaryAssetId" = "assets"."id" - or "assets"."stackId" is null + "assets"."deletedAt" is null + and "assets"."isVisible" = $2 + and date_trunc('MONTH', "localDateTime" at time zone 'UTC') at time zone 'UTC' = $3 + and not exists ( + select + from + "asset_stack" + where + "asset_stack"."id" = "assets"."stackId" + and "asset_stack"."primaryAssetId" != "assets"."id" + ) + order by + "assets"."localDateTime" desc + ), + "agg" as ( + select + coalesce(array_agg("city"), '{}') as "city", + coalesce(array_agg("country"), '{}') as "country", + coalesce(array_agg("duration"), '{}') as "duration", + coalesce(array_agg("id"), '{}') as "id", + coalesce(array_agg("isArchived"), '{}') as "isArchived", + coalesce(array_agg("isFavorite"), '{}') as "isFavorite", + coalesce(array_agg("isImage"), '{}') as "isImage", + coalesce(array_agg("isTrashed"), '{}') as "isTrashed", + coalesce(array_agg("livePhotoVideoId"), '{}') as "livePhotoVideoId", + coalesce(array_agg("localDateTime"), '{}') as "localDateTime", + coalesce(array_agg("ownerId"), '{}') as "ownerId", + coalesce(array_agg("projectionType"), '{}') as "projectionType", + coalesce(array_agg("ratio"), '{}') as "ratio", + coalesce(array_agg("status"), '{}') as "status", + coalesce(array_agg("thumbhash"), '{}') as "thumbhash", + coalesce(array_agg("stack"), '{}') as "stack" + from + "cte" ) - and "assets"."deletedAt" is null - and "assets"."isVisible" = $2 - and date_trunc($3, "localDateTime" at time zone 'UTC') at time zone 'UTC' = $4 -order by - "assets"."localDateTime" desc +select + to_json(agg)::text as "assets" +from + "agg" -- AssetRepository.getDuplicates with diff --git a/server/src/queries/person.repository.sql b/server/src/queries/person.repository.sql index f9ba32262d..3d751fac45 100644 --- a/server/src/queries/person.repository.sql +++ b/server/src/queries/person.repository.sql @@ -17,8 +17,6 @@ VACUUM ANALYZE asset_faces, face_search, person -REINDEX TABLE asset_faces -REINDEX TABLE person -- PersonRepository.delete delete from "person" @@ -33,8 +31,6 @@ VACUUM ANALYZE asset_faces, face_search, person -REINDEX TABLE asset_faces -REINDEX TABLE person -- PersonRepository.getAllWithoutFaces select diff --git a/server/src/repositories/asset.repository.ts b/server/src/repositories/asset.repository.ts index d191639fa7..2a8bdd9ed4 100644 --- a/server/src/repositories/asset.repository.ts +++ b/server/src/repositories/asset.repository.ts @@ -691,7 +691,9 @@ export class AssetRepository { eb.fn.coalesce(eb.fn('array_agg', ['status']), sql.lit('{}')).as('status'), eb.fn.coalesce(eb.fn('array_agg', ['thumbhash']), sql.lit('{}')).as('thumbhash'), ]) - .$if(!!options.withStacked, (qb) => qb.select((eb) => eb.fn('array_agg', ['stack']).as('stack'))), + .$if(!!options.withStacked, (qb) => + qb.select((eb) => eb.fn.coalesce(eb.fn('array_agg', ['stack']), sql.lit('{}')).as('stack')), + ), ) .selectFrom('agg') .select(sql`to_json(agg)::text`.as('assets'));