我有一个现有的 Postgres 9.3 数据库,其中包含一个包含 varchar 列的表。
Table "public.frontend_chemical"
Column | Type | Modifiers
-----------+------------------------+-----------
bnf_code | character varying(9) | not null
chem_name | character varying(200) | not null
我想在 chem_name
列上运行全文搜索。
我一直在读this article , 这表明步骤如下:
- 添加一个新的
tsvector
列:ALTER TABLE frontend_chemical ADD COLUMN fts_document tsvector;
- 创建一个函数以将
chem_name
列映射到文档,并创建一个触发器以使其保持更新。 - 在列上创建一个 GIN 索引:
CREATE INDEX chem_fts_index ON frontend_chemical USING(fts_document)
;
然后我应该能够运行全文搜索查询,例如:SELECT COUNT(*) FROM frontend_chemical WHERE fts_document @@ 'statin';
。
首先,这个一般过程是否正确?
其次,如何将 chem_name
列中的所有现有条目映射到 fts_document
列?文章中的示例似乎仅在更新 chem_name
列时更新 document
列,而我现有的数据库很大。
最佳答案
这个过程是正确的,但在你的情况下可能有点矫枉过正。
由于需要对单个列进行全文搜索,您可以取消专用的 tsvector
列,而只创建 GIN 索引:
CREATE INDEX chem_fts_index ON frontend_chemical
USING gin(to_tsvector('simple',chem_name));
您可以指定english
或其他可用的configuration,而不是simple
如果需要语言规则。
然后您将在搜索时从索引中受益:
select columns from frontend_chemical where
to_tsvector('simple', chem_name) @@ to_tsquery('simple','expression to search');
关键是 tsvector
表达式与 GIN 索引中的完全相同。
这样做的优点是不需要触发器,可以节省其值已经在索引中的专用列的空间,并且不需要初始化该列(您的第二个问题)。
如果您无论如何都想要该列,它应该首先用这种形式的更新查询填充:
UPDATE frontend_chemical SET fts_document = to_tsvector('simple', chem_name);
(再次假设 simple
作为文本搜索配置)
编辑以下评论:
to_tsquery()
只有一个参数使用默认文本配置(否则配置名称应作为第一个参数传递)。
如果此默认值与 to_tsvector
中使用的默认值不匹配,那就有问题了。可以通过多种方式更改默认值:
在 session 期间(不持久)
SET default_text_search_config to 'simple';
用于数据库(持久化)
ALTER DATABASE nameofdb SET default_text_search_config to 'simple';
否则,始终对
to_tsquery
使用双参数形式,并将显式文本配置名称作为第一个参数(我已将上面的示例更改为使用该形式)。
要使用 Ro
搜索您似乎想要的前缀,您可以使用以下条件:
to_tsvector('simple', chem_name) @@ to_tsquery('simple', 'Ro:*')
参见 Controlling Text Search在手册中了解更多信息。
关于postgresql - Postgres : Add full-text search on existing varchar column?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29649751/