1
0
forked from Cutlery/immich

handle multiple duplicateIds

This commit is contained in:
mertalev 2024-03-23 20:15:02 -04:00
parent 1c23977f25
commit 16d07dde8f
No known key found for this signature in database
GPG Key ID: 9181CD92C0A1C5E3
4 changed files with 14 additions and 9 deletions

View File

@ -3,7 +3,7 @@ import { AssetDuplicateEntity } from 'src/entities/asset-duplicate.entity';
export const IAssetDuplicateRepository = 'IAssetDuplicateRepository';
export interface IAssetDuplicateRepository {
create(duplicateId: string, assetIds: string[]): Promise<void>;
upsert(id: string, assetIds: string[], oldDuplicateIds?: string[]): Promise<void>;
delete(id: string): Promise<void>;
getById(id: string): Promise<AssetDuplicateEntity | null>;
}

View File

@ -4,21 +4,25 @@ import { AssetDuplicateEntity } from 'src/entities/asset-duplicate.entity';
import { AssetEntity } from 'src/entities/asset.entity';
import { IAssetDuplicateRepository } from 'src/interfaces/asset-duplicate.interface';
import { Instrumentation } from 'src/utils/instrumentation';
import { Repository } from 'typeorm';
import { In, Repository } from 'typeorm';
@Instrumentation()
@Injectable()
export class AssetDuplicateRepository implements IAssetDuplicateRepository {
constructor(@InjectRepository(AssetDuplicateEntity) private repository: Repository<AssetDuplicateEntity>) {}
async create(id: string, assetIds: string[]) {
async upsert(id: string, assetIds: string[], oldDuplicateIds: string[] = []): Promise<void> {
await this.repository.manager.transaction(async (manager) => {
await manager.upsert(
AssetDuplicateEntity,
assetIds.map((assetId) => ({ id, assetId })),
['assetId'],
);
await manager.update(AssetEntity, assetIds, { duplicateId: id });
if (oldDuplicateIds.length > 0) {
await manager.update(AssetDuplicateEntity, { id: In(oldDuplicateIds) }, { id });
}
await manager.update(AssetEntity, { id: In(assetIds) }, { duplicateId: id });
await manager.update(AssetEntity, { duplicateId: In(oldDuplicateIds) }, { duplicateId: id }); // TODO: cascade should handle this, but it doesn't seem to
});
}

View File

@ -163,10 +163,11 @@ export class SearchRepository implements ISearchRepository {
.addSelect(`(SELECT embedding FROM smart_search WHERE "assetId" = :assetId) <=> search.embedding`, 'distance')
.innerJoin('asset.smartSearch', 'search')
.where('asset.ownerId IN (:...userIds )')
.andWhere('asset.id != :assetId', { assetId })
.andWhere('asset.id != :assetId')
.andWhere('asset.isVisible = :isVisible')
.orderBy('search.embedding <=> (SELECT embedding FROM smart_search WHERE "assetId" = :assetId)')
.limit(64)
.setParameters({ assetId, userIds });
.setParameters({ assetId, isVisible: true, userIds });
const builder = this.assetRepository.manager
.createQueryBuilder()

View File

@ -213,13 +213,13 @@ export class SearchService {
if (duplicateAssets.length > 0) {
this.logger.debug(`Found ${duplicateAssets.length} duplicates for asset ${asset.id}`);
let duplicateId = duplicateAssets.find((duplicate) => duplicate.duplicateId)?.duplicateId;
duplicateId ??= this.cryptoRepository.randomUUID();
const duplicateIds = duplicateAssets.map((duplicate) => duplicate.duplicateId).filter(Boolean);
const duplicateId = duplicateIds[0] || this.cryptoRepository.randomUUID();
const duplicateAssetIds = duplicateAssets.map((duplicate) => duplicate.assetId);
duplicateAssetIds.push(asset.id);
await this.assetDuplicateRepository.create(duplicateId, duplicateAssetIds);
await this.assetDuplicateRepository.upsert(duplicateId, duplicateAssetIds, duplicateIds);
}
await this.assetRepository.upsertJobStatus({