mirror of
https://github.com/samsonjs/immich.git
synced 2026-03-25 09:15:56 +00:00
feat(server): Add album filter to search (#18985)
* - updated dtos - added inAlbums to search builder - only check isNotInAlbum if albumIds is blank/empty * - consider inAlbums as OR * - make open-api-dart * - lint & format * - remove inAlbums groupBy clause * - merge main open-api * - make open-api * - inAlbums filter AND instead of OR
This commit is contained in:
parent
242817c49a
commit
14d785cec9
9 changed files with 57 additions and 2 deletions
BIN
mobile/openapi/lib/model/metadata_search_dto.dart
generated
BIN
mobile/openapi/lib/model/metadata_search_dto.dart
generated
Binary file not shown.
BIN
mobile/openapi/lib/model/random_search_dto.dart
generated
BIN
mobile/openapi/lib/model/random_search_dto.dart
generated
Binary file not shown.
BIN
mobile/openapi/lib/model/smart_search_dto.dart
generated
BIN
mobile/openapi/lib/model/smart_search_dto.dart
generated
Binary file not shown.
BIN
mobile/openapi/lib/model/statistics_search_dto.dart
generated
BIN
mobile/openapi/lib/model/statistics_search_dto.dart
generated
Binary file not shown.
|
|
@ -10866,6 +10866,13 @@
|
|||
},
|
||||
"MetadataSearchDto": {
|
||||
"properties": {
|
||||
"albumIds": {
|
||||
"items": {
|
||||
"format": "uuid",
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"checksum": {
|
||||
"type": "string"
|
||||
},
|
||||
|
|
@ -11785,6 +11792,13 @@
|
|||
},
|
||||
"RandomSearchDto": {
|
||||
"properties": {
|
||||
"albumIds": {
|
||||
"items": {
|
||||
"format": "uuid",
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"city": {
|
||||
"nullable": true,
|
||||
"type": "string"
|
||||
|
|
@ -12833,6 +12847,13 @@
|
|||
},
|
||||
"SmartSearchDto": {
|
||||
"properties": {
|
||||
"albumIds": {
|
||||
"items": {
|
||||
"format": "uuid",
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"city": {
|
||||
"nullable": true,
|
||||
"type": "string"
|
||||
|
|
@ -13029,6 +13050,13 @@
|
|||
},
|
||||
"StatisticsSearchDto": {
|
||||
"properties": {
|
||||
"albumIds": {
|
||||
"items": {
|
||||
"format": "uuid",
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"city": {
|
||||
"nullable": true,
|
||||
"type": "string"
|
||||
|
|
|
|||
|
|
@ -853,6 +853,7 @@ export type SearchExploreResponseDto = {
|
|||
items: SearchExploreItem[];
|
||||
};
|
||||
export type MetadataSearchDto = {
|
||||
albumIds?: string[];
|
||||
checksum?: string;
|
||||
city?: string | null;
|
||||
country?: string | null;
|
||||
|
|
@ -929,6 +930,7 @@ export type PlacesResponseDto = {
|
|||
name: string;
|
||||
};
|
||||
export type RandomSearchDto = {
|
||||
albumIds?: string[];
|
||||
city?: string | null;
|
||||
country?: string | null;
|
||||
createdAfter?: string;
|
||||
|
|
@ -962,6 +964,7 @@ export type RandomSearchDto = {
|
|||
withStacked?: boolean;
|
||||
};
|
||||
export type SmartSearchDto = {
|
||||
albumIds?: string[];
|
||||
city?: string | null;
|
||||
country?: string | null;
|
||||
createdAfter?: string;
|
||||
|
|
@ -996,6 +999,7 @@ export type SmartSearchDto = {
|
|||
withExif?: boolean;
|
||||
};
|
||||
export type StatisticsSearchDto = {
|
||||
albumIds?: string[];
|
||||
city?: string | null;
|
||||
country?: string | null;
|
||||
createdAfter?: string;
|
||||
|
|
|
|||
|
|
@ -95,6 +95,9 @@ class BaseSearchDto {
|
|||
@ValidateUUID({ each: true, optional: true })
|
||||
tagIds?: string[];
|
||||
|
||||
@ValidateUUID({ each: true, optional: true })
|
||||
albumIds?: string[];
|
||||
|
||||
@Optional()
|
||||
@IsInt()
|
||||
@Max(5)
|
||||
|
|
|
|||
|
|
@ -91,6 +91,10 @@ export interface SearchTagOptions {
|
|||
tagIds?: string[];
|
||||
}
|
||||
|
||||
export interface SearchAlbumOptions {
|
||||
albumIds?: string[];
|
||||
}
|
||||
|
||||
export interface SearchOrderOptions {
|
||||
orderDirection?: 'asc' | 'desc';
|
||||
}
|
||||
|
|
@ -108,7 +112,8 @@ type BaseAssetSearchOptions = SearchDateOptions &
|
|||
SearchStatusOptions &
|
||||
SearchUserIdOptions &
|
||||
SearchPeopleOptions &
|
||||
SearchTagOptions;
|
||||
SearchTagOptions &
|
||||
SearchAlbumOptions;
|
||||
|
||||
export type AssetSearchOptions = BaseAssetSearchOptions & SearchRelationOptions;
|
||||
|
||||
|
|
|
|||
|
|
@ -228,6 +228,20 @@ export function hasPeople<O>(qb: SelectQueryBuilder<DB, 'assets', O>, personIds:
|
|||
);
|
||||
}
|
||||
|
||||
export function inAlbums<O>(qb: SelectQueryBuilder<DB, 'assets', O>, albumIds: string[]) {
|
||||
return qb.innerJoin(
|
||||
(eb) =>
|
||||
eb
|
||||
.selectFrom('albums_assets_assets')
|
||||
.select('assetsId')
|
||||
.where('albumsId', '=', anyUuid(albumIds!))
|
||||
.groupBy('assetsId')
|
||||
.having((eb) => eb.fn.count('albumsId').distinct(), '=', albumIds.length)
|
||||
.as('has_album'),
|
||||
(join) => join.onRef('has_album.assetsId', '=', 'assets.id'),
|
||||
);
|
||||
}
|
||||
|
||||
export function hasTags<O>(qb: SelectQueryBuilder<DB, 'assets', O>, tagIds: string[]) {
|
||||
return qb.innerJoin(
|
||||
(eb) =>
|
||||
|
|
@ -292,6 +306,7 @@ export function searchAssetBuilder(kysely: Kysely<DB>, options: AssetSearchBuild
|
|||
.withPlugin(joinDeduplicationPlugin)
|
||||
.selectFrom('assets')
|
||||
.where('assets.visibility', '=', visibility)
|
||||
.$if(!!options.albumIds && options.albumIds.length > 0, (qb) => inAlbums(qb, options.albumIds!))
|
||||
.$if(!!options.tagIds && options.tagIds.length > 0, (qb) => hasTags(qb, options.tagIds!))
|
||||
.$if(!!options.personIds && options.personIds.length > 0, (qb) => hasPeople(qb, options.personIds!))
|
||||
.$if(!!options.createdBefore, (qb) => qb.where('assets.createdAt', '<=', options.createdBefore!))
|
||||
|
|
@ -368,7 +383,7 @@ export function searchAssetBuilder(kysely: Kysely<DB>, options: AssetSearchBuild
|
|||
.$if(options.isMotion !== undefined, (qb) =>
|
||||
qb.where('assets.livePhotoVideoId', options.isMotion ? 'is not' : 'is', null),
|
||||
)
|
||||
.$if(!!options.isNotInAlbum, (qb) =>
|
||||
.$if(!!options.isNotInAlbum && (!options.albumIds || options.albumIds.length === 0), (qb) =>
|
||||
qb.where((eb) =>
|
||||
eb.not(eb.exists((eb) => eb.selectFrom('albums_assets_assets').whereRef('assetsId', '=', 'assets.id'))),
|
||||
),
|
||||
|
|
|
|||
Loading…
Reference in a new issue