1
0
Fork 0
mirror of https://github.com/immich-app/immich.git synced 2025-04-21 15:36:26 +02:00

fix(server): truncate embedding tables ()

truncate
This commit is contained in:
Mert 2024-02-27 10:24:23 -05:00 committed by GitHub
parent 9fa2424652
commit fb18129843
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 16 additions and 16 deletions

View file

@ -187,4 +187,5 @@ export interface ISearchRepository {
searchFaces(search: FaceEmbeddingSearch): Promise<FaceSearchResult[]>;
upsert(smartInfo: Partial<SmartInfoEntity>, embedding?: Embedding): Promise<void>;
searchPlaces(placeName: string): Promise<GeodataPlacesEntity[]>;
deleteAllSearchEmbeddings(): Promise<void>;
}

View file

@ -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();
});
});

View file

@ -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)

View file

@ -40,11 +40,11 @@ export class PersonRepository implements IPersonRepository {
}
async deleteAll(): Promise<void> {
await this.personRepository.delete({});
await this.personRepository.clear();
}
async deleteAllFaces(): Promise<void> {
await this.assetFaceRepository.delete({});
await this.assetFaceRepository.query('TRUNCATE TABLE asset_faces CASCADE');
}
getAllFaces(

View file

@ -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<void> {
return this.smartSearchRepository.clear();
}
private async getDimSize(): Promise<number> {
const res = await this.smartSearchRepository.manager.query(`
SELECT atttypmod as dimsize

View file

@ -8,5 +8,6 @@ export const newSearchRepositoryMock = (): jest.Mocked<ISearchRepository> => {
searchFaces: jest.fn(),
upsert: jest.fn(),
searchPlaces: jest.fn(),
deleteAllSearchEmbeddings: jest.fn(),
};
};