feat(server): search across own+partner assets (#5966)

* feat(server): search across own+partner assets

* generate sql

* fix sql parameter
This commit is contained in:
Fynn Petersen-Frey
2024-01-01 23:25:22 +01:00
committed by GitHub
parent 2688e05033
commit cc7ba3c21a
8 changed files with 44 additions and 21 deletions
@@ -804,10 +804,14 @@ export class AssetRepository implements IAssetRepository {
return builder;
}
@GenerateSql({ params: [DummyValue.STRING, DummyValue.UUID, { numResults: 250 }] })
async searchMetadata(query: string, ownerId: string, { numResults }: MetadataSearchOptions): Promise<AssetEntity[]> {
@GenerateSql({ params: [DummyValue.STRING, [DummyValue.UUID], { numResults: 250 }] })
async searchMetadata(
query: string,
userIds: string[],
{ numResults }: MetadataSearchOptions,
): Promise<AssetEntity[]> {
const rows = await this.getBuilder({
userIds: [ownerId],
userIds: userIds,
exifInfo: false,
isArchived: false,
})
@@ -41,9 +41,9 @@ export class SmartInfoRepository implements ISmartInfoRepository {
}
@GenerateSql({
params: [{ ownerId: DummyValue.UUID, embedding: Array.from({ length: 512 }, Math.random), numResults: 100 }],
params: [{ userIds: [DummyValue.UUID], embedding: Array.from({ length: 512 }, Math.random), numResults: 100 }],
})
async searchCLIP({ ownerId, embedding, numResults }: EmbeddingSearch): Promise<AssetEntity[]> {
async searchCLIP({ userIds, embedding, numResults }: EmbeddingSearch): Promise<AssetEntity[]> {
if (!isValidInteger(numResults, { min: 1 })) {
throw new Error(`Invalid value for 'numResults': ${numResults}`);
}
@@ -55,13 +55,13 @@ export class SmartInfoRepository implements ISmartInfoRepository {
results = await manager
.createQueryBuilder(AssetEntity, 'a')
.innerJoin('a.smartSearch', 's')
.where('a.ownerId = :ownerId')
.where('a.ownerId IN (:...userIds )')
.andWhere('a.isVisible = true')
.andWhere('a.isArchived = false')
.andWhere('a.fileCreatedAt < NOW()')
.leftJoinAndSelect('a.exifInfo', 'e')
.orderBy('s.embedding <=> :embedding')
.setParameters({ ownerId, embedding: asVector(embedding) })
.setParameters({ userIds, embedding: asVector(embedding) })
.limit(numResults)
.getMany();
});
@@ -72,14 +72,14 @@ export class SmartInfoRepository implements ISmartInfoRepository {
@GenerateSql({
params: [
{
ownerId: DummyValue.UUID,
userIds: [DummyValue.UUID],
embedding: Array.from({ length: 512 }, Math.random),
numResults: 100,
maxDistance: 0.6,
},
],
})
async searchFaces({ ownerId, embedding, numResults, maxDistance }: EmbeddingSearch): Promise<AssetFaceEntity[]> {
async searchFaces({ userIds, embedding, numResults, maxDistance }: EmbeddingSearch): Promise<AssetFaceEntity[]> {
if (!isValidInteger(numResults, { min: 1 })) {
throw new Error(`Invalid value for 'numResults': ${numResults}`);
}
@@ -91,9 +91,9 @@ export class SmartInfoRepository implements ISmartInfoRepository {
.createQueryBuilder(AssetFaceEntity, 'faces')
.select('1 + (faces.embedding <=> :embedding)', 'distance')
.innerJoin('faces.asset', 'asset')
.where('asset.ownerId = :ownerId')
.where('asset.ownerId IN (:...userIds )')
.orderBy('1 + (faces.embedding <=> :embedding)')
.setParameters({ ownerId, embedding: asVector(embedding) })
.setParameters({ userIds, embedding: asVector(embedding) })
.limit(numResults);
this.faceColumns.forEach((col) => cte.addSelect(`faces.${col}`, col));
@@ -69,7 +69,7 @@ FROM
LEFT JOIN "exif" "e" ON "e"."assetId" = "a"."id"
WHERE
(
"a"."ownerId" = $1
"a"."ownerId" IN ($1)
AND "a"."isVisible" = true
AND "a"."isArchived" = false
AND "a"."fileCreatedAt" < NOW()
@@ -103,7 +103,7 @@ WITH
INNER JOIN "assets" "asset" ON "asset"."id" = "faces"."assetId"
AND ("asset"."deletedAt" IS NULL)
WHERE
"asset"."ownerId" = $2
"asset"."ownerId" IN ($2)
ORDER BY
1 + ("faces"."embedding" <= > $3) ASC
LIMIT