Postgres:在现有的varchar列上添加全文搜索?

时间:2015-04-15 12:05:12

标签: postgresql

我有一个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,其中建议步骤如下:

  1. 添加新的tsvector列:ALTER TABLE frontend_chemical ADD COLUMN fts_document tsvector;
  2. 创建一个函数以将chem_name列映射到文档,并创建一个触发器以使其更新。
  3. 在列上创建GIN索引:CREATE INDEX chem_fts_index ON frontend_chemical USING gin(fts_document);
  4. 然后我应该可以运行全文搜索查询,例如:SELECT COUNT(*) FROM frontend_chemical WHERE fts_document @@ 'statin';

    首先,一般过程是否正确?

    其次,如何将chem_name列中的所有现有条目映射到fts_document列?本文中的示例似乎仅在document列更新时更新chem_name列,而我有一个大的现有数据库。

1 个答案:

答案 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的双参数形式,并使用显式文本配置名称作为第一个参数(我已更改上面的示例以使用该表单)。

    < / LI>

要使用 Ro 搜索您想要的前缀,您可以使用以下条件:

to_tsvector('simple', chem_name) @@ to_tsquery('simple', 'Ro:*')

有关详情,请参阅手册中的Controlling Text Search