mirror of
https://github.com/immich-app/immich.git
synced 2025-12-20 09:15:35 +03:00
feat: filter people when using smart search (#7521)
This commit is contained in:
@@ -122,6 +122,9 @@ class BaseSearchDto {
|
||||
|
||||
@QueryBoolean({ optional: true })
|
||||
isNotInAlbum?: boolean;
|
||||
|
||||
@Optional()
|
||||
personIds?: string[];
|
||||
}
|
||||
|
||||
export class MetadataSearchDto extends BaseSearchDto {
|
||||
@@ -173,9 +176,6 @@ export class MetadataSearchDto extends BaseSearchDto {
|
||||
@Optional()
|
||||
@ApiProperty({ enumName: 'AssetOrder', enum: AssetOrder })
|
||||
order?: AssetOrder;
|
||||
|
||||
@Optional()
|
||||
personIds?: string[];
|
||||
}
|
||||
|
||||
export class SmartSearchDto extends BaseSearchDto {
|
||||
|
||||
@@ -22,7 +22,7 @@ import {
|
||||
import { ImmichLogger } from '@app/infra/logger';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { Repository, SelectQueryBuilder } from 'typeorm';
|
||||
import { vectorExt } from '../database.config';
|
||||
import { DummyValue, GenerateSql } from '../infra.util';
|
||||
import { asVector, isValidInteger, paginatedBuilder, searchAssetBuilder } from '../infra.utils';
|
||||
@@ -81,6 +81,14 @@ export class SearchRepository implements ISearchRepository {
|
||||
});
|
||||
}
|
||||
|
||||
private createPersonFilter(builder: SelectQueryBuilder<AssetFaceEntity>, personIds: string[]) {
|
||||
return builder
|
||||
.select(`${builder.alias}."assetId"`)
|
||||
.where(`${builder.alias}."personId" IN (:...personIds)`, { personIds })
|
||||
.groupBy(`${builder.alias}."assetId"`)
|
||||
.having(`COUNT(DISTINCT ${builder.alias}."personId") = :personCount`, { personCount: personIds.length });
|
||||
}
|
||||
|
||||
@GenerateSql({
|
||||
params: [
|
||||
{ page: 1, size: 100 },
|
||||
@@ -96,12 +104,21 @@ export class SearchRepository implements ISearchRepository {
|
||||
})
|
||||
async searchSmart(
|
||||
pagination: SearchPaginationOptions,
|
||||
{ embedding, userIds, ...options }: SmartSearchOptions,
|
||||
{ embedding, userIds, personIds, ...options }: SmartSearchOptions,
|
||||
): Paginated<AssetEntity> {
|
||||
let results: PaginationResult<AssetEntity> = { items: [], hasNextPage: false };
|
||||
|
||||
await this.assetRepository.manager.transaction(async (manager) => {
|
||||
let builder = manager.createQueryBuilder(AssetEntity, 'asset');
|
||||
|
||||
if (personIds?.length) {
|
||||
const assetFaceBuilder = manager.createQueryBuilder(AssetFaceEntity, 'asset_face');
|
||||
const cte = this.createPersonFilter(assetFaceBuilder, personIds);
|
||||
builder
|
||||
.addCommonTableExpression(cte, 'asset_face_ids')
|
||||
.innerJoin('asset_face_ids', 'a', 'a."assetId" = asset.id');
|
||||
}
|
||||
|
||||
builder = searchAssetBuilder(builder, options);
|
||||
builder
|
||||
.innerJoin('asset.smartSearch', 'search')
|
||||
|
||||
Reference in New Issue
Block a user