我有一个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
列映射到文档,并创建一个触发器以使其更新。CREATE INDEX chem_fts_index ON frontend_chemical USING gin(fts_document)
; 然后我应该可以运行全文搜索查询,例如:SELECT COUNT(*) FROM frontend_chemical WHERE fts_document @@ 'statin';
。
首先,一般过程是否正确?
其次,如何将chem_name
列中的所有现有条目映射到fts_document
列?本文中的示例似乎仅在document
列更新时更新chem_name
列,而我有一个大的现有数据库。
答案 0 :(得分:8)
这个过程是正确的,但在您的情况下可能有点过分。
由于需要对单个列进行全文搜索,因此您可以取消专用的tsvector
列,并仅将GIN索引创建为:
CREATE INDEX chem_fts_index ON frontend_chemical
USING gin(to_tsvector('simple',chem_name));
如果需要语言规则,您可以指定simple
或其他可用configuration,而不是english
。
然后,在搜索时,您将从索引中受益:
select columns from frontend_chemical where
to_tsvector('simple', chem_name) @@ to_tsquery('simple','expression to search');
关键点是tsvector
表达式与GIN索引中的表达式完全相同。
这样做的好处是不需要触发器,保存其值已经在索引中的专用列的空间,并且不需要初始化该列(第2个问题)。
无论如何,如果您想要该列,最初应填充此表单的更新查询:
UPDATE frontend_chemical SET fts_document = to_tsvector('simple', chem_name);
(同样,假设simple
为文本搜索配置)
编辑以下评论:
只有一个参数的 to_tsquery()
使用默认文本配置(否则配置名称应作为第一个参数传递)。
如果此默认值与to_tsvector
中使用的默认值不匹配,则表示存在问题。可以通过多种方式更改默认值:
会话期间(非持久性)
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。