chore: improve randomness of /search/random endpoint (#27531)

This commit is contained in:
Steven Massaro
2026-04-16 10:36:05 -04:00
committed by GitHub
parent 3356e81c85
commit ac2ebcee37
2 changed files with 18 additions and 54 deletions
+15 -40
View File
@@ -35,47 +35,22 @@ where
and "asset"."deletedAt" is null and "asset"."deletedAt" is null
-- SearchRepository.searchRandom -- SearchRepository.searchRandom
( select
select "asset".*
"asset".* from
from "asset"
"asset" inner join "asset_exif" on "asset"."id" = "asset_exif"."assetId"
inner join "asset_exif" on "asset"."id" = "asset_exif"."assetId" where
where "asset"."visibility" = $1
"asset"."visibility" = $1 and "asset"."fileCreatedAt" >= $2
and "asset"."fileCreatedAt" >= $2 and "asset_exif"."lensModel" = $3
and "asset_exif"."lensModel" = $3 and "asset"."ownerId" = any ($4::uuid[])
and "asset"."ownerId" = any ($4::uuid[]) and "asset"."isFavorite" = $5
and "asset"."isFavorite" = $5 and "asset"."deletedAt" is null
and "asset"."deletedAt" is null order by
and "asset"."id" < $6 random()
order by
random()
limit
$7
)
union all
(
select
"asset".*
from
"asset"
inner join "asset_exif" on "asset"."id" = "asset_exif"."assetId"
where
"asset"."visibility" = $8
and "asset"."fileCreatedAt" >= $9
and "asset_exif"."lensModel" = $10
and "asset"."ownerId" = any ($11::uuid[])
and "asset"."isFavorite" = $12
and "asset"."deletedAt" is null
and "asset"."id" > $13
order by
random()
limit
$14
)
limit limit
$15 $6
-- SearchRepository.searchLargeAssets -- SearchRepository.searchLargeAssets
select select
+3 -14
View File
@@ -1,9 +1,7 @@
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { Kysely, OrderByDirection, Selectable, ShallowDehydrateObject, sql } from 'kysely'; import { Kysely, OrderByDirection, Selectable, ShallowDehydrateObject, sql } from 'kysely';
import { InjectKysely } from 'nestjs-kysely'; import { InjectKysely } from 'nestjs-kysely';
import { randomUUID } from 'node:crypto';
import { DummyValue, GenerateSql } from 'src/decorators'; import { DummyValue, GenerateSql } from 'src/decorators';
import { MapAsset } from 'src/dtos/asset-response.dto';
import { AssetStatus, AssetType, AssetVisibility, VectorIndex } from 'src/enum'; import { AssetStatus, AssetType, AssetVisibility, VectorIndex } from 'src/enum';
import { probes } from 'src/repositories/database.repository'; import { probes } from 'src/repositories/database.repository';
import { DB } from 'src/schema'; import { DB } from 'src/schema';
@@ -236,20 +234,11 @@ export class SearchRepository {
], ],
}) })
async searchRandom(size: number, options: AssetSearchOptions) { async searchRandom(size: number, options: AssetSearchOptions) {
const uuid = randomUUID(); return searchAssetBuilder(this.db, options)
const builder = searchAssetBuilder(this.db, options);
const lessThan = builder
.selectAll('asset') .selectAll('asset')
.where('asset.id', '<', uuid)
.orderBy(sql`random()`) .orderBy(sql`random()`)
.limit(size); .limit(size)
const greaterThan = builder .execute();
.selectAll('asset')
.where('asset.id', '>', uuid)
.orderBy(sql`random()`)
.limit(size);
const { rows } = await sql<MapAsset>`${lessThan} union all ${greaterThan} limit ${size}`.execute(this.db);
return rows;
} }
@GenerateSql({ @GenerateSql({