From 2550453ee46563526b215e37605c8c66d3b97267 Mon Sep 17 00:00:00 2001 From: MartinBraquet Date: Wed, 10 Sep 2025 22:50:20 +0200 Subject: [PATCH] Add keyword search --- backend/api/src/get-lovers.ts | 2 +- backend/supabase/migration.sql | 3 +++ .../migrations/20250410042701_add_report.sql | 23 ------------------- .../migrations/20250910_add_bio_text.sql | 22 ++++++++++++++++++ .../migrations/20250910_bio_to_jsonb.sql | 5 ++++ .../supabase/migrations/20250910_pg_trgm.sql | 4 ++++ web/components/filters/search.tsx | 2 +- web/components/profiles/profiles-home.tsx | 9 ++++++-- 8 files changed, 43 insertions(+), 27 deletions(-) delete mode 100644 backend/supabase/migrations/20250410042701_add_report.sql create mode 100644 backend/supabase/migrations/20250910_add_bio_text.sql create mode 100644 backend/supabase/migrations/20250910_bio_to_jsonb.sql create mode 100644 backend/supabase/migrations/20250910_pg_trgm.sql diff --git a/backend/api/src/get-lovers.ts b/backend/api/src/get-lovers.ts index 66ced361..8fa752dd 100644 --- a/backend/api/src/get-lovers.ts +++ b/backend/api/src/get-lovers.ts @@ -83,7 +83,7 @@ export const getLovers: APIHandler<'get-lovers'> = async (props, _auth) => { where(`data->>'userDeleted' != 'true' or data->>'userDeleted' is null`), name && - where(`lower(users.name) ilike '%' || lower($(name)) || '%'`, { name }), + where(`lower(users.name) ilike '%' || lower($(name)) || '%' or lower(bio::text) ilike '%' || lower($(name)) || '%'`, { name }), genders?.length && where(`gender = ANY($(gender))`, { gender: genders }), diff --git a/backend/supabase/migration.sql b/backend/supabase/migration.sql index afb8b7f6..609bd71b 100644 --- a/backend/supabase/migration.sql +++ b/backend/supabase/migration.sql @@ -20,4 +20,7 @@ BEGIN; \i backend/supabase/user_notifications.sql \i backend/supabase/functions_others.sql \i backend/supabase/reports.sql +\i backend/supabase/migrations/20250910_bio_to_jsonb.sql +\i backend/supabase/migrations/20250910_add_bio_text.sql +\i backend/supabase/migrations/20250910_pg_trgm.sql COMMIT; diff --git a/backend/supabase/migrations/20250410042701_add_report.sql b/backend/supabase/migrations/20250410042701_add_report.sql deleted file mode 100644 index 8b21437e..00000000 --- a/backend/supabase/migrations/20250410042701_add_report.sql +++ /dev/null @@ -1,23 +0,0 @@ --- This file is copied from https://github.com/manifoldmarkets/manifold/blob/main/backend/supabase/reports.sql -create table if not exists - reports ( - content_id text not null, - content_owner_id text not null, - content_type text not null, - created_time timestamp with time zone default now(), - description text, - id text default uuid_generate_v4 () not null, - parent_id text, - parent_type text, - user_id text not null - ); - --- Foreign Keys -alter table reports -add constraint reports_content_owner_id_fkey foreign key (content_owner_id) references users (id); - -alter table reports -add constraint reports_user_id_fkey foreign key (user_id) references users (id); - --- Row Level Security -alter table reports enable row level security; diff --git a/backend/supabase/migrations/20250910_add_bio_text.sql b/backend/supabase/migrations/20250910_add_bio_text.sql new file mode 100644 index 00000000..1a6de3c3 --- /dev/null +++ b/backend/supabase/migrations/20250910_add_bio_text.sql @@ -0,0 +1,22 @@ +ALTER TABLE lovers ADD COLUMN bio_text tsvector; + +CREATE OR REPLACE FUNCTION lovers_bio_tsvector_update() +RETURNS trigger AS $$ +BEGIN + new.bio_text := to_tsvector( + 'english', + ( + SELECT string_agg(trim(both '"' from x::text), ' ') + FROM jsonb_path_query(new.bio, '$.**.text'::jsonpath) AS x + ) + ); +RETURN new; +END; +$$ LANGUAGE plpgsql; + +CREATE TRIGGER lovers_bio_tsvector_trigger + BEFORE INSERT OR UPDATE OF bio ON lovers + FOR EACH ROW EXECUTE FUNCTION lovers_bio_tsvector_update(); + + +create index on lovers using gin(bio_text); diff --git a/backend/supabase/migrations/20250910_bio_to_jsonb.sql b/backend/supabase/migrations/20250910_bio_to_jsonb.sql new file mode 100644 index 00000000..37354989 --- /dev/null +++ b/backend/supabase/migrations/20250910_bio_to_jsonb.sql @@ -0,0 +1,5 @@ +-- 1. Drop the old column +alter table lovers drop column if exists bio; + +-- 2. Add the new column as jsonb +alter table lovers add column bio jsonb; diff --git a/backend/supabase/migrations/20250910_pg_trgm.sql b/backend/supabase/migrations/20250910_pg_trgm.sql new file mode 100644 index 00000000..3d157f86 --- /dev/null +++ b/backend/supabase/migrations/20250910_pg_trgm.sql @@ -0,0 +1,4 @@ +create extension if not exists pg_trgm; + +CREATE INDEX lovers_bio_trgm_idx + ON lovers USING gin ((bio::text) gin_trgm_ops); diff --git a/web/components/filters/search.tsx b/web/components/filters/search.tsx index 73fa3d56..14479940 100644 --- a/web/components/filters/search.tsx +++ b/web/components/filters/search.tsx @@ -61,7 +61,7 @@ export const Search = (props: { { updateFilter({ name: e.target.value }) diff --git a/web/components/profiles/profiles-home.tsx b/web/components/profiles/profiles-home.tsx index 4bf48de3..712356eb 100644 --- a/web/components/profiles/profiles-home.tsx +++ b/web/components/profiles/profiles-home.tsx @@ -53,7 +53,11 @@ export function ProfilesHome() { if (!user) return; setIsReloading(true); const current = ++id.current; - api('get-lovers', removeNullOrUndefinedProps({limit: 20, compatibleWithUserId: user?.id, ...filters}) as any) + api('get-lovers', removeNullOrUndefinedProps({ + limit: 20, + compatibleWithUserId: user?.id, + ...filters + }) as any) .then(({lovers}) => { if (current === id.current) setLovers(lovers); }) @@ -74,7 +78,8 @@ export function ProfilesHome() { const result = await api('get-lovers', removeNullOrUndefinedProps({ limit: 20, compatibleWithUserId: user?.id, - after: lastLover?.id.toString(), ...filters + after: lastLover?.id.toString(), + ...filters }) as any); if (result.lovers.length === 0) return false; setLovers((prev) => (prev ? [...prev, ...result.lovers] : result.lovers));