diff --git a/server/src/domain/repositories/search.repository.ts b/server/src/domain/repositories/search.repository.ts index 8566fcd8e50b9..c9fec3cf71c79 100644 --- a/server/src/domain/repositories/search.repository.ts +++ b/server/src/domain/repositories/search.repository.ts @@ -187,4 +187,5 @@ export interface ISearchRepository { searchFaces(search: FaceEmbeddingSearch): Promise; upsert(smartInfo: Partial, embedding?: Embedding): Promise; searchPlaces(placeName: string): Promise; + deleteAllSearchEmbeddings(): Promise; } diff --git a/server/src/domain/smart-info/smart-info.service.spec.ts b/server/src/domain/smart-info/smart-info.service.spec.ts index 5da7b7824bb98..9835ea1a53521 100644 --- a/server/src/domain/smart-info/smart-info.service.spec.ts +++ b/server/src/domain/smart-info/smart-info.service.spec.ts @@ -71,6 +71,7 @@ describe(SmartInfoService.name, () => { expect(jobMock.queueAll).toHaveBeenCalledWith([{ name: JobName.SMART_SEARCH, data: { id: assetStub.image.id } }]); expect(assetMock.getWithout).toHaveBeenCalledWith({ skip: 0, take: 1000 }, WithoutProperty.SMART_SEARCH); + expect(searchMock.deleteAllSearchEmbeddings).not.toHaveBeenCalled(); }); it('should queue all the assets', async () => { @@ -83,6 +84,7 @@ describe(SmartInfoService.name, () => { expect(jobMock.queueAll).toHaveBeenCalledWith([{ name: JobName.SMART_SEARCH, data: { id: assetStub.image.id } }]); expect(assetMock.getAll).toHaveBeenCalled(); + expect(searchMock.deleteAllSearchEmbeddings).toHaveBeenCalled(); }); }); diff --git a/server/src/domain/smart-info/smart-info.service.ts b/server/src/domain/smart-info/smart-info.service.ts index d193b29b510c3..19d5668cc5a93 100644 --- a/server/src/domain/smart-info/smart-info.service.ts +++ b/server/src/domain/smart-info/smart-info.service.ts @@ -50,6 +50,10 @@ export class SmartInfoService { return true; } + if (force) { + await this.repository.deleteAllSearchEmbeddings(); + } + const assetPagination = usePagination(JOBS_ASSET_PAGINATION_SIZE, (pagination) => { return force ? this.assetRepository.getAll(pagination) diff --git a/server/src/infra/repositories/person.repository.ts b/server/src/infra/repositories/person.repository.ts index 63b3d570efa5e..3a7ec29466d3d 100644 --- a/server/src/infra/repositories/person.repository.ts +++ b/server/src/infra/repositories/person.repository.ts @@ -40,11 +40,11 @@ export class PersonRepository implements IPersonRepository { } async deleteAll(): Promise { - await this.personRepository.delete({}); + await this.personRepository.clear(); } async deleteAllFaces(): Promise { - await this.assetFaceRepository.delete({}); + await this.assetFaceRepository.query('TRUNCATE TABLE asset_faces CASCADE'); } getAllFaces( diff --git a/server/src/infra/repositories/search.repository.ts b/server/src/infra/repositories/search.repository.ts index 089640128c890..c8dc5070f753c 100644 --- a/server/src/infra/repositories/search.repository.ts +++ b/server/src/infra/repositories/search.repository.ts @@ -229,25 +229,17 @@ export class SearchRepository implements ISearchRepository { this.logger.log(`Updating database CLIP dimension size to ${dimSize}.`); await this.smartSearchRepository.manager.transaction(async (manager) => { - await manager.query(`DROP TABLE smart_search`); - - await manager.query(` - CREATE TABLE smart_search ( - "assetId" uuid PRIMARY KEY REFERENCES assets(id) ON DELETE CASCADE, - embedding vector(${dimSize}) NOT NULL )`); - - await manager.query(` - CREATE INDEX clip_index ON smart_search - USING vectors (embedding vector_cos_ops) WITH (options = $$ - [indexing.hnsw] - m = 16 - ef_construction = 300 - $$)`); + await manager.clear(SmartSearchEntity); + await manager.query(`ALTER TABLE smart_search ALTER COLUMN embedding SET DATA TYPE vector(${dimSize})`); }); this.logger.log(`Successfully updated database CLIP dimension size from ${curDimSize} to ${dimSize}.`); } + deleteAllSearchEmbeddings(): Promise { + return this.smartSearchRepository.clear(); + } + private async getDimSize(): Promise { const res = await this.smartSearchRepository.manager.query(` SELECT atttypmod as dimsize diff --git a/server/test/repositories/search.repository.mock.ts b/server/test/repositories/search.repository.mock.ts index 06a2cb76d02db..5912d77451f45 100644 --- a/server/test/repositories/search.repository.mock.ts +++ b/server/test/repositories/search.repository.mock.ts @@ -8,5 +8,6 @@ export const newSearchRepositoryMock = (): jest.Mocked => { searchFaces: jest.fn(), upsert: jest.fn(), searchPlaces: jest.fn(), + deleteAllSearchEmbeddings: jest.fn(), }; };