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 const IAssetDuplicateRepository = 'IAssetDuplicateRepository';
|
||||||
|
|
||||||
export interface 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>;
|
delete(id: string): Promise<void>;
|
||||||
getById(id: string): Promise<AssetDuplicateEntity | null>;
|
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 { AssetEntity } from 'src/entities/asset.entity';
|
||||||
import { IAssetDuplicateRepository } from 'src/interfaces/asset-duplicate.interface';
|
import { IAssetDuplicateRepository } from 'src/interfaces/asset-duplicate.interface';
|
||||||
import { Instrumentation } from 'src/utils/instrumentation';
|
import { Instrumentation } from 'src/utils/instrumentation';
|
||||||
import { Repository } from 'typeorm';
|
import { In, Repository } from 'typeorm';
|
||||||
|
|
||||||
@Instrumentation()
|
@Instrumentation()
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AssetDuplicateRepository implements IAssetDuplicateRepository {
|
export class AssetDuplicateRepository implements IAssetDuplicateRepository {
|
||||||
constructor(@InjectRepository(AssetDuplicateEntity) private repository: Repository<AssetDuplicateEntity>) {}
|
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 this.repository.manager.transaction(async (manager) => {
|
||||||
await manager.upsert(
|
await manager.upsert(
|
||||||
AssetDuplicateEntity,
|
AssetDuplicateEntity,
|
||||||
assetIds.map((assetId) => ({ id, assetId })),
|
assetIds.map((assetId) => ({ id, assetId })),
|
||||||
['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')
|
.addSelect(`(SELECT embedding FROM smart_search WHERE "assetId" = :assetId) <=> search.embedding`, 'distance')
|
||||||
.innerJoin('asset.smartSearch', 'search')
|
.innerJoin('asset.smartSearch', 'search')
|
||||||
.where('asset.ownerId IN (:...userIds )')
|
.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)')
|
.orderBy('search.embedding <=> (SELECT embedding FROM smart_search WHERE "assetId" = :assetId)')
|
||||||
.limit(64)
|
.limit(64)
|
||||||
.setParameters({ assetId, userIds });
|
.setParameters({ assetId, isVisible: true, userIds });
|
||||||
|
|
||||||
const builder = this.assetRepository.manager
|
const builder = this.assetRepository.manager
|
||||||
.createQueryBuilder()
|
.createQueryBuilder()
|
||||||
|
@ -213,13 +213,13 @@ export class SearchService {
|
|||||||
if (duplicateAssets.length > 0) {
|
if (duplicateAssets.length > 0) {
|
||||||
this.logger.debug(`Found ${duplicateAssets.length} duplicates for asset ${asset.id}`);
|
this.logger.debug(`Found ${duplicateAssets.length} duplicates for asset ${asset.id}`);
|
||||||
|
|
||||||
let duplicateId = duplicateAssets.find((duplicate) => duplicate.duplicateId)?.duplicateId;
|
const duplicateIds = duplicateAssets.map((duplicate) => duplicate.duplicateId).filter(Boolean);
|
||||||
duplicateId ??= this.cryptoRepository.randomUUID();
|
const duplicateId = duplicateIds[0] || this.cryptoRepository.randomUUID();
|
||||||
|
|
||||||
const duplicateAssetIds = duplicateAssets.map((duplicate) => duplicate.assetId);
|
const duplicateAssetIds = duplicateAssets.map((duplicate) => duplicate.assetId);
|
||||||
duplicateAssetIds.push(asset.id);
|
duplicateAssetIds.push(asset.id);
|
||||||
|
|
||||||
await this.assetDuplicateRepository.create(duplicateId, duplicateAssetIds);
|
await this.assetDuplicateRepository.upsert(duplicateId, duplicateAssetIds, duplicateIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.assetRepository.upsertJobStatus({
|
await this.assetRepository.upsertJobStatus({
|
||||||
|
Loading…
x
Reference in New Issue
Block a user