forked from Cutlery/immich
handle multiple duplicateIds
This commit is contained in:
parent
1c23977f25
commit
16d07dde8f
@ -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>;
|
||||
}
|
||||
|
@ -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
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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({
|
||||
|
Loading…
x
Reference in New Issue
Block a user