fix(server): people sorting (#3713)

This commit is contained in:
martin 2023-08-16 02:06:49 +02:00 committed by GitHub
parent 0abbd85134
commit c27c12d975
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 18 additions and 9 deletions

View file

@ -4,6 +4,7 @@ export const IPersonRepository = 'IPersonRepository';
export interface PersonSearchOptions { export interface PersonSearchOptions {
minimumFaceCount: number; minimumFaceCount: number;
withHidden: boolean;
} }
export interface UpdateFacesData { export interface UpdateFacesData {

View file

@ -47,7 +47,7 @@ describe(PersonService.name, () => {
visible: 1, visible: 1,
people: [responseDto], people: [responseDto],
}); });
expect(personMock.getAll).toHaveBeenCalledWith(authStub.admin.id, { minimumFaceCount: 1 }); expect(personMock.getAll).toHaveBeenCalledWith(authStub.admin.id, { minimumFaceCount: 1, withHidden: false });
}); });
it('should get all visible people with thumbnails', async () => { it('should get all visible people with thumbnails', async () => {
personMock.getAll.mockResolvedValue([personStub.withName, personStub.hidden]); personMock.getAll.mockResolvedValue([personStub.withName, personStub.hidden]);
@ -56,7 +56,7 @@ describe(PersonService.name, () => {
visible: 1, visible: 1,
people: [responseDto], people: [responseDto],
}); });
expect(personMock.getAll).toHaveBeenCalledWith(authStub.admin.id, { minimumFaceCount: 1 }); expect(personMock.getAll).toHaveBeenCalledWith(authStub.admin.id, { minimumFaceCount: 1, withHidden: false });
}); });
it('should get all hidden and visible people with thumbnails', async () => { it('should get all hidden and visible people with thumbnails', async () => {
personMock.getAll.mockResolvedValue([personStub.withName, personStub.hidden]); personMock.getAll.mockResolvedValue([personStub.withName, personStub.hidden]);
@ -73,7 +73,7 @@ describe(PersonService.name, () => {
}, },
], ],
}); });
expect(personMock.getAll).toHaveBeenCalledWith(authStub.admin.id, { minimumFaceCount: 1 }); expect(personMock.getAll).toHaveBeenCalledWith(authStub.admin.id, { minimumFaceCount: 1, withHidden: true });
}); });
}); });

View file

@ -26,8 +26,10 @@ export class PersonService {
) {} ) {}
async getAll(authUser: AuthUserDto, dto: PersonSearchDto): Promise<PeopleResponseDto> { async getAll(authUser: AuthUserDto, dto: PersonSearchDto): Promise<PeopleResponseDto> {
const people = await this.repository.getAll(authUser.id, { minimumFaceCount: 1 }); const people = await this.repository.getAll(authUser.id, {
minimumFaceCount: 1,
withHidden: dto.withHidden || false,
});
const persons: PersonResponseDto[] = people const persons: PersonResponseDto[] = people
// with thumbnails // with thumbnails
.filter((person) => !!person.thumbnailPath) .filter((person) => !!person.thumbnailPath)

View file

@ -51,16 +51,22 @@ export class PersonRepository implements IPersonRepository {
} }
getAll(userId: string, options?: PersonSearchOptions): Promise<PersonEntity[]> { getAll(userId: string, options?: PersonSearchOptions): Promise<PersonEntity[]> {
return this.personRepository const queryBuilder = this.personRepository
.createQueryBuilder('person') .createQueryBuilder('person')
.leftJoin('person.faces', 'face') .leftJoin('person.faces', 'face')
.where('person.ownerId = :userId', { userId }) .where('person.ownerId = :userId', { userId })
.orderBy('COUNT(face.assetId)', 'DESC') .orderBy('person.isHidden', 'ASC')
.addOrderBy("NULLIF(person.name, '') IS NULL", 'ASC')
.addOrderBy('COUNT(face.assetId)', 'DESC')
.addOrderBy("NULLIF(person.name, '')", 'ASC', 'NULLS LAST') .addOrderBy("NULLIF(person.name, '')", 'ASC', 'NULLS LAST')
.having('COUNT(face.assetId) >= :faces', { faces: options?.minimumFaceCount || 1 }) .having('COUNT(face.assetId) >= :faces', { faces: options?.minimumFaceCount || 1 })
.groupBy('person.id') .groupBy('person.id')
.limit(500) .limit(500);
.getMany(); if (!options?.withHidden) {
queryBuilder.andWhere('person.isHidden = false');
}
return queryBuilder.getMany();
} }
getAllWithoutFaces(): Promise<PersonEntity[]> { getAllWithoutFaces(): Promise<PersonEntity[]> {