diff --git a/server/src/domain/repositories/asset.repository.ts b/server/src/domain/repositories/asset.repository.ts index ba1848202..e68c8888b 100644 --- a/server/src/domain/repositories/asset.repository.ts +++ b/server/src/domain/repositories/asset.repository.ts @@ -1,7 +1,7 @@ +import { SearchExploreItem } from '@app/domain'; import { AssetEntity, AssetJobStatusEntity, AssetType, ExifEntity } from '@app/infra/entities'; import { FindOptionsRelations } from 'typeorm'; import { Paginated, PaginationOptions } from '../domain.util'; -import { SearchExploreItem } from '../repositories'; export type AssetStats = Record; diff --git a/server/src/domain/repositories/smart-info.repository.ts b/server/src/domain/repositories/smart-info.repository.ts index 533aecf1f..d78bb5ad0 100644 --- a/server/src/domain/repositories/smart-info.repository.ts +++ b/server/src/domain/repositories/smart-info.repository.ts @@ -1,5 +1,5 @@ +import { Embedding, EmbeddingSearch } from '@app/domain'; import { AssetEntity, SmartInfoEntity } from '@app/infra/entities'; -import { Embedding, EmbeddingSearch } from '../repositories'; export const ISmartInfoRepository = 'ISmartInfoRepository'; diff --git a/server/src/domain/search/search.service.ts b/server/src/domain/search/search.service.ts index 6f4c22c8d..563a521a0 100644 --- a/server/src/domain/search/search.service.ts +++ b/server/src/domain/search/search.service.ts @@ -18,7 +18,6 @@ import { SearchResponseDto } from './response-dto'; @Injectable() export class SearchService { - private timer: NodeJS.Timeout | null = null; private logger = new Logger(SearchService.name); private configCore: SystemConfigCore; diff --git a/server/src/immich/main.ts b/server/src/immich/main.ts index 832d988af..647957aa4 100644 --- a/server/src/immich/main.ts +++ b/server/src/immich/main.ts @@ -1,5 +1,5 @@ import { envName, getLogLevels, isDev, serverVersion } from '@app/domain'; -import { RedisIoAdapter } from '@app/infra'; +import { RedisIoAdapter, runVectorMigrations } from '@app/infra'; import { Logger } from '@nestjs/common'; import { NestFactory } from '@nestjs/core'; import { NestExpressApplication } from '@nestjs/platform-express'; @@ -29,6 +29,8 @@ export async function bootstrap() { app.useStaticAssets('www'); app.use(indexFallback(excludePaths)); + await runVectorMigrations(); + const server = await app.listen(port); server.requestTimeout = 30 * 60 * 1000; diff --git a/server/src/infra/database.config.ts b/server/src/infra/database.config.ts index c3e04ca7d..20289723c 100644 --- a/server/src/infra/database.config.ts +++ b/server/src/infra/database.config.ts @@ -29,8 +29,13 @@ export const databaseConfigVector: PostgresConnectionOptions = { migrations: [__dirname + '/migrations/vector/*.{js,ts}'], }; -export async function initDataSource(): Promise { - const dataSource = await new DataSource(databaseConfig).initialize(); +// this export is used by TypeORM commands in package.json#scripts +export let dataSource = new DataSource(databaseConfig); + +export async function runVectorMigrations(): Promise { + if (!dataSource.isInitialized) { + dataSource = await dataSource.initialize(); + } const hasVectorExtension = (await dataSource.query( `SELECT * FROM pg_available_extensions WHERE name = 'vectors'`, @@ -44,12 +49,4 @@ export async function initDataSource(): Promise { await dataSourceVector.destroy(); } - - return dataSource; } - -// this export is used by TypeORM commands in package.json#scripts -export let dataSource: DataSource; -(async () => { - dataSource = await initDataSource(); -})(); diff --git a/server/src/infra/entities/asset.entity.ts b/server/src/infra/entities/asset.entity.ts index 247903209..07de00685 100644 --- a/server/src/infra/entities/asset.entity.ts +++ b/server/src/infra/entities/asset.entity.ts @@ -20,9 +20,9 @@ import { ExifEntity } from './exif.entity'; import { LibraryEntity } from './library.entity'; import { SharedLinkEntity } from './shared-link.entity'; import { SmartInfoEntity } from './smart-info.entity'; +import { SmartSearchEntity } from './smart-search.entity'; import { TagEntity } from './tag.entity'; import { UserEntity } from './user.entity'; -import { SmartSearchEntity } from '.'; export const ASSET_CHECKSUM_CONSTRAINT = 'UQ_assets_owner_library_checksum'; diff --git a/server/src/infra/repositories/smart-info.repository.ts b/server/src/infra/repositories/smart-info.repository.ts index 33e787105..66fdf5c2e 100644 --- a/server/src/infra/repositories/smart-info.repository.ts +++ b/server/src/infra/repositories/smart-info.repository.ts @@ -89,12 +89,12 @@ export class SmartInfoRepository implements ISmartInfoRepository { embedding vector(${dimSize}) NOT NULL )`); await manager.query(` - CREATE INDEX clip_index ON smart_search - USING vectors (embedding cosine_ops) WITH (options = $$ - [indexing.hnsw] - m = 16 - ef_construction = 300 - $$)`); + CREATE INDEX clip_index ON smart_search + USING vectors (embedding cosine_ops) WITH (options = $$ + [indexing.hnsw] + m = 16 + ef_construction = 300 + $$)`); }); this.curDimSize = dimSize;