任务:在 PostgreSQL 中的多个表中实现全文搜索。
比如一个项目表——projects:有两个字段需要搜索:title和description。在这个表上创建一个索引:
ALTER TABLE public.projects ADD COLUMN search_fts tsvector;
UPDATE public.projects SET search_fts =
to_tsvector(
coalesce(title, '') ||' '||
coalesce(description, '') || ' '
);
CREATE INDEX in_projects_idx ON public.projects
USING gin (search_fts);
现在搜索很简单:
SELECT
DISTINCT p.id,
p.title,
ts_rank(
p.search_fts,
to_tsquery('word1 | word2')
) as rank
FROM
projects p
WHERE
p.search_fts @@ to_tsquery('word1 | word2')
ORDER BY rank DESC;
精致。现在我们需要查看表和项目类别——project_categories。类似于创建 tsvector 和为表上的字段名。现在的搜索查询是:
SELECT
DISTINCT p.id,
p.title,
category.name as categoryName,
ts_rank(
(
coalesce(p.search_fts, '') ||' '||
coalesce(category.search_fts, '')
),
to_tsquery('word1 | word2 | categoryName')
) as rank
FROM
projects p
LEFT JOIN project_categories category
ON p.category_id = category.category_id
WHERE
(
coalesce(p.search_fts, '') ||' '||
coalesce(category.search_fts, '')
) @@ to_tsquery('word1 | word2 | categoryName')
ORDER BY rank DESC;
更精致。现在搜索必须以一对多和多对多的形式在几十个与项目相关的表上工作。
加入人数越来越多。结合到越来越多的领域。
实际上这个问题是我要去的正确方式吗?你将如何解决这个问题?
我也考虑了有视图的版本。例如,基于这样的请求:
(
SELECT
p.id as project_id,
p.search_fts
FROM projects p
) UNION ALL (
SELECT
p.id as project_id,
category.search_fts
FROM projects p
JOIN project_categories category
ON p.category_id = category.category_id
)
最后,我们得到整体指数。通过哪个搜索。但在视图中必须结合十几个不同通信选项的请求。对您对此选项的看法感兴趣。
对不起我的英语不好。