mirror of
https://github.com/immich-app/immich.git
synced 2025-12-23 17:25:11 +03:00
feat(server): CLIP search integration (#1939)
This commit is contained in:
@@ -15,4 +15,14 @@ export class SmartInfoEntity {
|
||||
|
||||
@Column({ type: 'text', array: true, nullable: true })
|
||||
objects!: string[] | null;
|
||||
|
||||
@Column({
|
||||
type: 'numeric',
|
||||
array: true,
|
||||
nullable: true,
|
||||
// note: migration generator is broken for numeric[], but these _are_ set in the database
|
||||
// precision: 20,
|
||||
// scale: 19,
|
||||
})
|
||||
clipEmbedding!: number[] | null;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
export class AddCLIPEncodeDataColumn1677971458822 implements MigrationInterface {
|
||||
name = 'AddCLIPEncodeDataColumn1677971458822';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "smart_info" ADD "clipEmbedding" numeric(20,19) array`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "smart_info" DROP COLUMN "clipEmbedding"`);
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,34 @@
|
||||
import { IAlbumRepository } from '@app/domain';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { In, Repository } from 'typeorm';
|
||||
import { AlbumEntity } from '../entities';
|
||||
|
||||
@Injectable()
|
||||
export class AlbumRepository implements IAlbumRepository {
|
||||
constructor(@InjectRepository(AlbumEntity) private repository: Repository<AlbumEntity>) {}
|
||||
|
||||
getByIds(ids: string[]): Promise<AlbumEntity[]> {
|
||||
return this.repository.find({
|
||||
where: {
|
||||
id: In(ids),
|
||||
},
|
||||
relations: {
|
||||
owner: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async deleteAll(userId: string): Promise<void> {
|
||||
await this.repository.delete({ ownerId: userId });
|
||||
}
|
||||
|
||||
getAll(): Promise<AlbumEntity[]> {
|
||||
return this.repository.find();
|
||||
return this.repository.find({
|
||||
relations: {
|
||||
owner: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async save(album: Partial<AlbumEntity>) {
|
||||
|
||||
@@ -1,13 +1,24 @@
|
||||
import { AssetSearchOptions, IAssetRepository } from '@app/domain';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Not, Repository } from 'typeorm';
|
||||
import { In, Not, Repository } from 'typeorm';
|
||||
import { AssetEntity, AssetType } from '../entities';
|
||||
|
||||
@Injectable()
|
||||
export class AssetRepository implements IAssetRepository {
|
||||
constructor(@InjectRepository(AssetEntity) private repository: Repository<AssetEntity>) {}
|
||||
|
||||
getByIds(ids: string[]): Promise<AssetEntity[]> {
|
||||
return this.repository.find({
|
||||
where: { id: In(ids) },
|
||||
relations: {
|
||||
exifInfo: true,
|
||||
smartInfo: true,
|
||||
tags: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async deleteAll(ownerId: string): Promise<void> {
|
||||
await this.repository.delete({ ownerId });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user