任务: 在PostgreSQL中的多个表中实现全文搜索。
例如,一个项目表 - 项目: 需要搜索的字段有两个:标题和说明。 在此表上创建索引:
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
)
最后,我们获得整体指数。通过它搜索。 但在视图中必须结合十几个请求进行各种通信选项。 对您对此选项的看法感兴趣。
抱歉我的英文。
答案 0 :(得分:3)
您有几个选择:
在所有输入表上使用触发器来维护一个汇总表,该表汇总了文本行中感兴趣的所有记录。对于包含1个或多个customer
和一个或多个phone
条目的address
等简单案例,这可以正常运行,您可以将其作为{{1}放在摘要搜索表中在连接表上使用简单连接和|customername|customerid|phone1|phone2|phone3|...|address1|address2|...
。但是,它很难扩展到深层嵌套的关系,并且可能会产生一些锁定和并发问题。
使用像Apache Solr这样的外部搜索系统来解决复杂的搜索问题。