mirror of
https://github.com/immich-app/immich.git
synced 2026-03-04 09:57:33 +03:00
fix(server): "all" button for facial recognition deleting faces instead of unassigning them (#13042)
* unassign faces instead of deleting them * formatting
This commit is contained in:
@@ -9,13 +9,14 @@ import { PersonEntity } from 'src/entities/person.entity';
|
||||
import { PaginationMode, SourceType } from 'src/enum';
|
||||
import {
|
||||
AssetFaceId,
|
||||
DeleteAllFacesOptions,
|
||||
DeleteFacesOptions,
|
||||
IPersonRepository,
|
||||
PeopleStatistics,
|
||||
PersonNameResponse,
|
||||
PersonNameSearchOptions,
|
||||
PersonSearchOptions,
|
||||
PersonStatistics,
|
||||
UnassignFacesOptions,
|
||||
UpdateFacesData,
|
||||
} from 'src/interfaces/person.interface';
|
||||
import { Instrumentation } from 'src/utils/instrumentation';
|
||||
@@ -39,12 +40,23 @@ export class PersonRepository implements IPersonRepository {
|
||||
.createQueryBuilder()
|
||||
.update()
|
||||
.set({ personId: newPersonId })
|
||||
.where(_.omitBy({ personId: oldPersonId ?? undefined, id: faceIds ? In(faceIds) : undefined }, _.isUndefined))
|
||||
.where(_.omitBy({ personId: oldPersonId, id: faceIds ? In(faceIds) : undefined }, _.isUndefined))
|
||||
.execute();
|
||||
|
||||
return result.affected ?? 0;
|
||||
}
|
||||
|
||||
async unassignFaces({ sourceType }: UnassignFacesOptions): Promise<void> {
|
||||
await this.assetFaceRepository
|
||||
.createQueryBuilder()
|
||||
.update()
|
||||
.set({ personId: null })
|
||||
.where({ sourceType })
|
||||
.execute();
|
||||
|
||||
await this.vacuum({ reindexVectors: false });
|
||||
}
|
||||
|
||||
async delete(entities: PersonEntity[]): Promise<void> {
|
||||
await this.personRepository.remove(entities);
|
||||
}
|
||||
@@ -53,21 +65,14 @@ export class PersonRepository implements IPersonRepository {
|
||||
await this.personRepository.clear();
|
||||
}
|
||||
|
||||
async deleteAllFaces({ sourceType }: DeleteAllFacesOptions): Promise<void> {
|
||||
if (!sourceType) {
|
||||
return this.assetFaceRepository.query('TRUNCATE TABLE asset_faces CASCADE');
|
||||
}
|
||||
|
||||
async deleteFaces({ sourceType }: DeleteFacesOptions): Promise<void> {
|
||||
await this.assetFaceRepository
|
||||
.createQueryBuilder('asset_faces')
|
||||
.delete()
|
||||
.andWhere('sourceType = :sourceType', { sourceType })
|
||||
.execute();
|
||||
|
||||
await this.assetFaceRepository.query('VACUUM ANALYZE asset_faces, face_search');
|
||||
if (sourceType === SourceType.MACHINE_LEARNING) {
|
||||
await this.assetFaceRepository.query('REINDEX INDEX face_index');
|
||||
}
|
||||
await this.vacuum({ reindexVectors: sourceType === SourceType.MACHINE_LEARNING });
|
||||
}
|
||||
|
||||
getAllFaces(
|
||||
@@ -331,4 +336,13 @@ export class PersonRepository implements IPersonRepository {
|
||||
const { id } = await this.personRepository.save(person);
|
||||
return this.personRepository.findOneByOrFail({ id });
|
||||
}
|
||||
|
||||
private async vacuum({ reindexVectors }: { reindexVectors: boolean }): Promise<void> {
|
||||
await this.assetFaceRepository.query('VACUUM ANALYZE asset_faces, face_search, person');
|
||||
await this.assetFaceRepository.query('REINDEX TABLE asset_faces');
|
||||
await this.assetFaceRepository.query('REINDEX TABLE person');
|
||||
if (reindexVectors) {
|
||||
await this.assetFaceRepository.query('REINDEX TABLE face_search');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user