chore(server): remove old asset search (#9104)

* chore(server): remove old asset search

* chore: remove more unused search code
This commit is contained in:
Jason Rasmussen
2024-04-27 08:57:39 -04:00
committed by GitHub
parent 0c60aaf557
commit 5a49de5592
20 changed files with 30 additions and 1801 deletions

View File

@@ -1,6 +1,4 @@
import { mapAsset } from 'src/dtos/asset-response.dto';
import { SearchDto } from 'src/dtos/search.dto';
import { SystemConfigKey } from 'src/entities/system-config.entity';
import { IAssetRepository } from 'src/interfaces/asset.interface';
import { ILoggerRepository } from 'src/interfaces/logger.interface';
import { IMachineLearningRepository } from 'src/interfaces/machine-learning.interface';
@@ -97,119 +95,4 @@ describe(SearchService.name, () => {
expect(result).toEqual(expectedResponse);
});
});
describe('search', () => {
it('should throw an error if query is missing', async () => {
await expect(sut.search(authStub.user1, { q: '' })).rejects.toThrow('Missing query');
});
it('should search by metadata if `clip` option is false', async () => {
const dto: SearchDto = { q: 'test query', clip: false };
assetMock.searchMetadata.mockResolvedValueOnce([assetStub.image]);
partnerMock.getAll.mockResolvedValueOnce([]);
const expectedResponse = {
albums: {
total: 0,
count: 0,
items: [],
facets: [],
},
assets: {
total: 1,
count: 1,
items: [mapAsset(assetStub.image)],
facets: [],
nextPage: null,
},
};
const result = await sut.search(authStub.user1, dto);
expect(result).toEqual(expectedResponse);
expect(assetMock.searchMetadata).toHaveBeenCalledWith(dto.q, [authStub.user1.user.id], { numResults: 250 });
expect(searchMock.searchSmart).not.toHaveBeenCalled();
});
it('should search archived photos if `withArchived` option is true', async () => {
const dto: SearchDto = { q: 'test query', clip: true, withArchived: true };
const embedding = [1, 2, 3];
searchMock.searchSmart.mockResolvedValueOnce({ items: [assetStub.image], hasNextPage: false });
machineMock.encodeText.mockResolvedValueOnce(embedding);
partnerMock.getAll.mockResolvedValueOnce([]);
const expectedResponse = {
albums: {
total: 0,
count: 0,
items: [],
facets: [],
},
assets: {
total: 1,
count: 1,
items: [mapAsset(assetStub.image)],
facets: [],
nextPage: null,
},
};
const result = await sut.search(authStub.user1, dto);
expect(result).toEqual(expectedResponse);
expect(searchMock.searchSmart).toHaveBeenCalledWith(
{ page: 1, size: 100 },
{
userIds: [authStub.user1.user.id],
embedding,
withArchived: true,
},
);
expect(assetMock.searchMetadata).not.toHaveBeenCalled();
});
it('should search by CLIP if `clip` option is true', async () => {
const dto: SearchDto = { q: 'test query', clip: true };
const embedding = [1, 2, 3];
searchMock.searchSmart.mockResolvedValueOnce({ items: [assetStub.image], hasNextPage: false });
machineMock.encodeText.mockResolvedValueOnce(embedding);
partnerMock.getAll.mockResolvedValueOnce([]);
const expectedResponse = {
albums: {
total: 0,
count: 0,
items: [],
facets: [],
},
assets: {
total: 1,
count: 1,
items: [mapAsset(assetStub.image)],
facets: [],
nextPage: null,
},
};
const result = await sut.search(authStub.user1, dto);
expect(result).toEqual(expectedResponse);
expect(searchMock.searchSmart).toHaveBeenCalledWith(
{ page: 1, size: 100 },
{
userIds: [authStub.user1.user.id],
embedding,
withArchived: false,
},
);
expect(assetMock.searchMetadata).not.toHaveBeenCalled();
});
it.each([
{ key: SystemConfigKey.MACHINE_LEARNING_ENABLED },
{ key: SystemConfigKey.MACHINE_LEARNING_CLIP_ENABLED },
])('should throw an error if clip is requested but disabled', async ({ key }) => {
const dto: SearchDto = { q: 'test query', clip: true };
configMock.load.mockResolvedValue([{ key, value: false }]);
await expect(sut.search(authStub.user1, dto)).rejects.toThrow('Smart search is not enabled');
});
});
});

View File

@@ -6,7 +6,6 @@ import { PersonResponseDto } from 'src/dtos/person.dto';
import {
MetadataSearchDto,
PlacesResponseDto,
SearchDto,
SearchPeopleDto,
SearchPlacesDto,
SearchResponseDto,
@@ -23,7 +22,7 @@ import { IMachineLearningRepository } from 'src/interfaces/machine-learning.inte
import { IMetadataRepository } from 'src/interfaces/metadata.interface';
import { IPartnerRepository } from 'src/interfaces/partner.interface';
import { IPersonRepository } from 'src/interfaces/person.interface';
import { ISearchRepository, SearchExploreItem, SearchStrategy } from 'src/interfaces/search.interface';
import { ISearchRepository, SearchExploreItem } from 'src/interfaces/search.interface';
import { ISystemConfigRepository } from 'src/interfaces/system-config.interface';
@Injectable()
@@ -145,60 +144,6 @@ export class SearchService {
}
}
// TODO: remove after implementing new search filters
/** @deprecated */
async search(auth: AuthDto, dto: SearchDto): Promise<SearchResponseDto> {
await this.configCore.requireFeature(FeatureFlag.SEARCH);
const { machineLearning } = await this.configCore.getConfig();
const query = dto.q || dto.query;
if (!query) {
throw new Error('Missing query');
}
let strategy = SearchStrategy.TEXT;
if (dto.smart || dto.clip) {
await this.configCore.requireFeature(FeatureFlag.SMART_SEARCH);
strategy = SearchStrategy.SMART;
}
const userIds = await this.getUserIdsToSearch(auth);
const page = dto.page ?? 1;
let nextPage: string | null = null;
let assets: AssetEntity[] = [];
switch (strategy) {
case SearchStrategy.SMART: {
const embedding = await this.machineLearning.encodeText(
machineLearning.url,
{ text: query },
machineLearning.clip,
);
const { hasNextPage, items } = await this.searchRepository.searchSmart(
{ page, size: dto.size || 100 },
{
userIds,
embedding,
withArchived: !!dto.withArchived,
},
);
if (hasNextPage) {
nextPage = (page + 1).toString();
}
assets = items;
break;
}
case SearchStrategy.TEXT: {
assets = await this.assetRepository.searchMetadata(query, userIds, { numResults: dto.size || 250 });
}
default: {
break;
}
}
return this.mapResponse(assets, nextPage);
}
private async getUserIdsToSearch(auth: AuthDto): Promise<string[]> {
const userIds: string[] = [auth.user.id];
const partners = await this.partnerRepository.getAll(auth.user.id);