Skip to content

Commit daf5350

Browse files
committed
Add stem vector search in bio
1 parent 020b9dd commit daf5350

4 files changed

Lines changed: 42 additions & 26 deletions

File tree

backend/api/src/get-profiles.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ export const loadProfiles = async (props: profileQueryType) => {
109109
where(`data->>'userDeleted' != 'true' or data->>'userDeleted' is null`),
110110

111111
...keywords.map(word => where(
112-
`lower(users.name) ilike '%' || lower($(word)) || '%' or lower(bio::text) ilike '%' || lower($(word)) || '%'`,
112+
`lower(users.name) ilike '%' || lower($(word)) || '%' or lower(bio::text) ilike '%' || lower($(word)) || '%' or bio_tsv @@ phraseto_tsquery('english', $(word))`,
113113
{word}
114114
)),
115115

backend/shared/src/love/supabase.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,14 @@ export function convertRow(row: ProfileAndUserRow): Profile
1414
export function convertRow(row: ProfileAndUserRow | undefined): Profile | null {
1515
if (!row) return null
1616

17-
return {
17+
// Remove internal/search-only fields from the returned profile row
18+
const profile: any = {
1819
...row,
1920
user: { ...row.user, name: row.name, username: row.username } as User,
20-
} as Profile
21+
}
22+
delete profile.bio_text
23+
delete profile.bio_tsv
24+
return profile as Profile
2125
}
2226

2327
const LOVER_COLS = 'profiles.*, name, username, users.data as user'

backend/supabase/profiles.sql

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -115,25 +115,31 @@ CREATE INDEX profiles_bio_trgm_idx
115115

116116

117117
--- bio_text
118-
-- ALTER TABLE profiles ADD COLUMN bio_text tsvector;
119-
--
120-
-- CREATE OR REPLACE FUNCTION profiles_bio_tsvector_update()
121-
-- RETURNS trigger AS $$
122-
-- BEGIN
123-
-- new.bio_text := to_tsvector(
124-
-- 'english',
125-
-- (
126-
-- SELECT string_agg(trim(both '"' from x::text), ' ')
127-
-- FROM jsonb_path_query(new.bio, '$.**.text'::jsonpath) AS x
128-
-- )
129-
-- );
130-
-- RETURN new;
131-
-- END;
132-
-- $$ LANGUAGE plpgsql;
133-
--
134-
-- CREATE TRIGGER profiles_bio_tsvector_trigger
135-
-- BEFORE INSERT OR UPDATE OF bio ON profiles
136-
-- FOR EACH ROW EXECUTE FUNCTION profiles_bio_tsvector_update();
137-
--
138-
-- create index on profiles using gin(bio_text);
118+
ALTER TABLE profiles ADD COLUMN bio_text TEXT;
119+
UPDATE profiles
120+
SET bio_text = (
121+
SELECT string_agg(DISTINCT trim(both '"' from value::text), ' ')
122+
FROM jsonb_path_query(bio, '$.**.text') AS t(value)
123+
);
124+
125+
ALTER TABLE profiles ADD COLUMN bio_tsv tsvector
126+
GENERATED ALWAYS AS (to_tsvector('english', coalesce(bio_text, ''))) STORED;
127+
128+
CREATE INDEX profiles_bio_tsv_idx ON profiles USING GIN (bio_tsv);
129+
130+
CREATE OR REPLACE FUNCTION update_bio_text()
131+
RETURNS trigger AS $$
132+
BEGIN
133+
NEW.bio_text := (
134+
SELECT string_agg(DISTINCT trim(both '"' from value::text), ' ')
135+
FROM jsonb_path_query(NEW.bio, '$.**.text') AS t(value)
136+
);
137+
RETURN NEW;
138+
END;
139+
$$ LANGUAGE plpgsql;
140+
141+
CREATE TRIGGER trg_update_bio_text
142+
BEFORE INSERT OR UPDATE OF bio ON profiles
143+
FOR EACH ROW EXECUTE FUNCTION update_bio_text();
144+
139145

common/src/supabase/schema.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,8 @@ export type Database = {
406406
age: number | null
407407
bio: Json | null
408408
bio_length: number | null
409+
bio_text: string | null
410+
bio_tsv: unknown | null
409411
born_in_location: string | null
410412
city: string
411413
city_latitude: number | null
@@ -452,6 +454,8 @@ export type Database = {
452454
age?: number | null
453455
bio?: Json | null
454456
bio_length?: number | null
457+
bio_text?: string | null
458+
bio_tsv?: unknown | null
455459
born_in_location?: string | null
456460
city: string
457461
city_latitude?: number | null
@@ -467,7 +471,7 @@ export type Database = {
467471
geodb_city_id?: string | null
468472
has_kids?: number | null
469473
height_in_inches?: number | null
470-
id?: never
474+
id?: number
471475
is_smoker?: boolean | null
472476
is_vegetarian_or_vegan?: boolean | null
473477
last_modification_time?: string
@@ -498,6 +502,8 @@ export type Database = {
498502
age?: number | null
499503
bio?: Json | null
500504
bio_length?: number | null
505+
bio_text?: string | null
506+
bio_tsv?: unknown | null
501507
born_in_location?: string | null
502508
city?: string
503509
city_latitude?: number | null
@@ -513,7 +519,7 @@ export type Database = {
513519
geodb_city_id?: string | null
514520
has_kids?: number | null
515521
height_in_inches?: number | null
516-
id?: never
522+
id?: number
517523
is_smoker?: boolean | null
518524
is_vegetarian_or_vegan?: boolean | null
519525
last_modification_time?: string

0 commit comments

Comments
 (0)