Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: enhance search #7127

Merged
merged 34 commits into from
Feb 17, 2024
Merged

feat: enhance search #7127

merged 34 commits into from
Feb 17, 2024

Conversation

alextran1502
Copy link
Contributor

@alextran1502 alextran1502 commented Feb 15, 2024

This PR implements the rest of the search filter logic to search and render assets.

  • The search result view is now justified.
  • Search filter is memorized across view.

Copy link

cloudflare-workers-and-pages bot commented Feb 15, 2024

Deploying with  Cloudflare Pages  Cloudflare Pages

Latest commit: 1f3ac7a
Status: ✅  Deploy successful!
Preview URL: https://9df534b6.immich.pages.dev
Branch Preview URL: https://feat-hybrid-search.immich.pages.dev

View logs

@alextran1502 alextran1502 marked this pull request as draft February 15, 2024 05:15
Copy link
Contributor

@mertalev mertalev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there might be some confusion here. What this PR adds on the server side already exists in the current smart search endpoint. A hybrid search endpoint would just also do full-text search on certain fields and isn't necessary for the current filters on the frontend.

server/src/infra/repositories/search.repository.ts Outdated Show resolved Hide resolved
server/src/infra/repositories/search.repository.ts Outdated Show resolved Hide resolved
server/src/domain/search/search.service.ts Outdated Show resolved Hide resolved
web/src/routes/(user)/search/+page.svelte Outdated Show resolved Hide resolved
web/src/routes/(user)/search/+page.svelte Outdated Show resolved Hide resolved
q: searchValue,
smart: smartSearch,
take: '100',
q: JSON.stringify(payload),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems strange to have a full JSON as the value of q. Wouldn't it be better for each filter to be a different parameter?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes easier downstream to grab the whole string as JSON string and decode into javascript object

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You made the search endpoints POST, so what's the purpose of doing this instead of putting the JSON in the body?

web/src/routes/(user)/search/+page.svelte Outdated Show resolved Hide resolved
server/src/domain/search/dto/search.dto.ts Outdated Show resolved Hide resolved
server/src/domain/search/dto/search.dto.ts Outdated Show resolved Hide resolved
server/src/infra/repositories/search.repository.ts Outdated Show resolved Hide resolved
web/src/routes/(user)/search/+page.ts Outdated Show resolved Hide resolved
@alextran1502 alextran1502 changed the title feat: hybrid search feat: enhancesearch Feb 16, 2024
@alextran1502 alextran1502 changed the title feat: enhancesearch feat: enhance search Feb 16, 2024
@alextran1502 alextran1502 marked this pull request as ready for review February 16, 2024 20:51
server/src/domain/repositories/search.repository.ts Outdated Show resolved Hide resolved
@@ -169,6 +169,12 @@ export class MetadataSearchDto extends BaseSearchDto {
@Optional()
@ApiProperty({ enumName: 'AssetOrder', enum: AssetOrder })
order?: AssetOrder;

@QueryBoolean({ optional: true })
isNotInAlbum?: boolean;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I personally prefer not having negated variables. So I would like to have isInAlbum and if that's false, the asset should not be in an album.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about that as well, but to keep things easy to follow from the UI perspective specifically search for not in album. I think the name is justified to have not in it

Comment on lines +142 to +152
const hasExifQuery = Object.keys(exifInfo).length > 0;

if (options.withExif && !hasExifQuery) {
builder.leftJoinAndSelect(`${builder.alias}.exifInfo`, 'exifInfo');
}

if (hasExifQuery) {
options.withExif
? builder.leftJoinAndSelect(`${builder.alias}.exifInfo`, 'exifInfo')
: builder.leftJoin(`${builder.alias}.exifInfo`, 'exifInfo');

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you want to refactor this with what I had proposed on discord?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no clean syntax for builder.select() i.e. builder.select('exifInfo.*') unfortunately

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure there is either builder.select('exifInfo') or builder.select('exifInfo.*')

Copy link
Contributor Author

@alextran1502 alextran1502 Feb 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I tried both and they don't work :/

server/src/infra/repositories/search.repository.ts Outdated Show resolved Hide resolved
@alextran1502 alextran1502 merged commit 69983ff into main Feb 17, 2024
25 checks passed
@alextran1502 alextran1502 deleted the feat/hybrid-search branch February 17, 2024 17:00
.leftJoin(`${builder.alias}.faces`, 'faces')
.andWhere('faces.personId IN (:...personIds)', { personIds: options.personIds })
.addGroupBy(`${builder.alias}.id`)
.having('COUNT(faces.id) = :personCount', { personCount: options.personIds.length });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this. Why are we checking that the face count is equal to the person count?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let say you select people A and people B. Without that condition, the result will include people A only or people B only. We want the result includes both people A and people B altogether

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants