我正在开发一个多租户网络应用程序,我想添加全文搜索,以便人们能够:
1)仅搜索他们当前访问的网站(但不是所有网站),以及
2)仅搜索该网站的一部分(例如,限制搜索到该网站上的博客或论坛),以及
3)仅搜索单个论坛帖子。
我想知道我应该添加哪些索引?
请假设数据库很大(例如,索引按站点ID扫描,然后按全文搜索过滤太慢)。
我可以想到三种方法:
创建三个索引。 1)基于每个站点索引所有内容的索引。 2)在每个站点和站点部分的基础上索引所有内容的索引。 3)根据每个站点和页面ID对所有内容编制索引。
创建一个单一索引,并插入[要索引的文本]魔术词,如: “的site_<站点-ID>” 中 和“section_< section-id>”和“page_< page-id>”,然后当我搜索 对于网站YYY中的XX部分,我可以为搜索查询添加前缀,如下所示: “site_XX AND section_YYY AND ...”。
创建新网站或网站部分时动态添加数据库索引:
create index dw1_posts__search_site_YYY
on dw1_posts using gin(to_tsvector('english', approved_text))
where site_id = 'YYY';
上述三种方法中的任何一种都有意义吗?还有更好的选择吗?
(细节:但是,也许方法1是不可能的?尝试索引列和同时索引全文搜索会导致语法错误:
> create index dw1_posts__search_site
on dw1_posts (site_id)
using gin(to_tsvector('english', approved_text));
ERROR: syntax error at or near "using"
LINE 1: ...dex dw1_posts__search_site on dw1_posts(site_id) using gin(...
^
> create index dw1_posts__search_site
on dw1_posts
using gin(to_tsvector('english', approved_text))
(site_id);
ERROR: syntax error at or near "("
LINE 1: ... using gin(to_tsvector('english', approved_text)) (site_id);
(如果方法1 可能,那么我可以进行如下查询:
select ... from ... where site_id = ... and <full-text-search-column> @@ <query>;
让PostgreSQL首先检查site_id,然后使用一个索引检查全文搜索列。)
)
/ End details。)
更新,一周后:我正在使用ElasticSearch。我得到的印象是,对于带有关系数据库/ PostgreSQL的分面搜索,不存在可扩展的解决方案。与ElasticSearch集成似乎与实现和测试以及调整此处建议的方法一样简单。 (例如,PostgreSQL的词干分析器/无论它叫什么,可能会将“section_NNN”分成两个词:“section”和“NNN”,从而在页面上不存在索引词!解决这些小烦恼问题的棘手问题。)
答案 0 :(得分:1)
通常的做法是创建:
一个全文索引:
CREATE INDEX idx1 ON dw1_posts使用杜松子酒(to_tsvector('english',approved_text));
site_id上的一个简单索引:
CREATE INDEX idx2 在dw1_posts(page_id);
page_id上的另一个简单索引:
CREATE INDEX idx3 在dw1_posts(site_id);
然后,SQL计划员的业务决定使用哪些,以及依赖于查询和列中值的分布的顺序。在你真正目睹慢查询之前,试图超越计划者毫无意义。
答案 1 :(得分:0)
另一种替代方案,类似于“site_&lt; site-id&gt;”和“section_&lt; section-id&gt;”和“page_&lt; page-id&gt;”替代方案,应该是将文本添加到 index 的前缀:
SiteSectionPage_<site-id>_<section-id>_<subsection-id>_<page-id>
然后在搜索时使用prefix matching (i.e. :*
):
select ... from .. where .. @@ 'SiteSectionPage_NN_MMM:* AND (the search phrase)'
其中NN是网站ID,MMM是部门ID。
但这对中国人不起作用?我认为三元组在索引中文时是合适的,但是SiteSectionPage ...将被分成: Sit,ite,teS,eSe ,这没有任何意义。