【发布时间】:2013-07-13 14:35:48
【问题描述】:
我正在开发一个多租户 Web 应用程序,我想添加全文搜索,以便人们能够:
1) 仅搜索他们当前正在访问的网站(但不是所有网站),并且
2) 仅搜索该网站的一部分(例如,将搜索限制为网站上的博客或论坛),并且
3) 仅搜索单个论坛主题。
我想知道我应该添加哪些索引?
请假设数据库很大(例如,按站点 ID 进行索引扫描,然后按全文搜索进行过滤太慢了)。
我能想到三种方法:
创建三个索引。 1) 一个基于每个站点索引所有内容的索引。 和 2) 一个在每个站点加上站点部分的基础上索引所有内容的索引。 3) 一个基于每个站点和页面 ID 索引所有内容的索引。
创建一个单一的索引,并插入到 [要索引的文本] 中,如: “站点_” 和“section_
”和“page_ ”,然后当我搜索 对于站点 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,然后使用一个索引检查全文搜索列。)
)
/ 结束详情。)
一周后更新:我改用ElasticSearch。我的印象是,对于分面搜索,关系数据库/PostgreSQL 不存在可扩展的解决方案。与 ElasticSearch 集成似乎与实施、测试和调整此处建议的方法一样简单。 (例如,PostgreSQL 的词干分析器/它的名称可能会将“section_NNN”拆分为两个词:“section”和“NNN”,从而索引页面上不存在的词!修复这些烦人的小问题很棘手。)
【问题讨论】:
标签: postgresql full-text-search categories faceted-search