mirror of
https://github.com/immich-app/immich.git
synced 2026-03-07 02:27:23 +03:00
fix(server): /search/random failing with certain options (#13040)
* fix relation handling, remove pagination * update api, sql * update mock
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { randomUUID } from 'node:crypto';
|
||||
import { getVectorExtension } from 'src/database.config';
|
||||
import { DummyValue, GenerateSql } from 'src/decorators';
|
||||
import { AssetFaceEntity } from 'src/entities/asset-face.entity';
|
||||
@@ -63,22 +64,15 @@ export class SearchRepository implements ISearchRepository {
|
||||
{
|
||||
takenAfter: DummyValue.DATE,
|
||||
lensModel: DummyValue.STRING,
|
||||
ownerId: DummyValue.UUID,
|
||||
withStacked: true,
|
||||
isFavorite: true,
|
||||
ownerIds: [DummyValue.UUID],
|
||||
userIds: [DummyValue.UUID],
|
||||
},
|
||||
],
|
||||
})
|
||||
async searchMetadata(pagination: SearchPaginationOptions, options: AssetSearchOptions): Paginated<AssetEntity> {
|
||||
let builder = this.assetRepository.createQueryBuilder('asset');
|
||||
builder = searchAssetBuilder(builder, options);
|
||||
builder.orderBy('asset.fileCreatedAt', options.orderDirection ?? 'DESC');
|
||||
|
||||
if (options.random) {
|
||||
// TODO replace with complicated SQL magic after kysely migration
|
||||
builder.addSelect('RANDOM() as r').orderBy('r');
|
||||
}
|
||||
builder = searchAssetBuilder(builder, options).orderBy('asset.fileCreatedAt', options.orderDirection ?? 'DESC');
|
||||
|
||||
return paginatedBuilder<AssetEntity>(builder, {
|
||||
mode: PaginationMode.SKIP_TAKE,
|
||||
@@ -87,6 +81,35 @@ export class SearchRepository implements ISearchRepository {
|
||||
});
|
||||
}
|
||||
|
||||
@GenerateSql({
|
||||
params: [
|
||||
100,
|
||||
{
|
||||
takenAfter: DummyValue.DATE,
|
||||
lensModel: DummyValue.STRING,
|
||||
withStacked: true,
|
||||
isFavorite: true,
|
||||
userIds: [DummyValue.UUID],
|
||||
},
|
||||
],
|
||||
})
|
||||
async searchRandom(size: number, options: AssetSearchOptions): Promise<AssetEntity[]> {
|
||||
const builder1 = searchAssetBuilder(this.assetRepository.createQueryBuilder('asset'), options);
|
||||
const builder2 = builder1.clone();
|
||||
|
||||
const uuid = randomUUID();
|
||||
builder1.andWhere('asset.id > :uuid', { uuid }).orderBy('asset.id').take(size);
|
||||
builder2.andWhere('asset.id < :uuid', { uuid }).orderBy('asset.id').take(size);
|
||||
|
||||
const [assets1, assets2] = await Promise.all([builder1.getMany(), builder2.getMany()]);
|
||||
const missingCount = size - assets1.length;
|
||||
for (let i = 0; i < missingCount && i < assets2.length; i++) {
|
||||
assets1.push(assets2[i]);
|
||||
}
|
||||
|
||||
return assets1;
|
||||
}
|
||||
|
||||
private createPersonFilter(builder: SelectQueryBuilder<AssetFaceEntity>, personIds: string[]) {
|
||||
return builder
|
||||
.select(`${builder.alias}."assetId"`)
|
||||
|
||||
Reference in New Issue
Block a user