Postgres文本搜索派生的ts_vector

时间:2012-11-08 01:31:45

标签: postgresql full-text-search

不知怎的,我已经欺骗自己在数据库上编写全文搜索实现。我有一个代表我数据库中所有实体的表,一个表示所有标签的表,以及一个表示标签与实体的多对多关系的表。

我编写了一个查询,该查询将给定实体的所有标记名称分组,并将它们连接成一个字符串,然后我将其转换为ts_vector。该查询如下所示:

SELECT e.id, to_tsvector(c.publicname || ' ' || string_agg(cv.name, ' '))
FROM categoryvalue cv, entitycategoryvalue ecv, entity e 
WHERE ccv.categoryvalueid = cv.id AND e.id = ecv.entityid
GROUP BY e.id;

查询返回此架构中的结果:

id | to_tsvector
1  | tag_a, tag_b, tag_c
2  | tag_b, tag_d, tag_e

这正是我想要与ts_query匹配的内容。我虽然是SQL的菜鸟,但我想知道是否有一种方法可以创建一个不断更新的表,我已经编写了查询结果?

编辑:我在此博文中记录了我的最终解决方案和系统http://tech.pro/tutorial/1142/building-faceted-search-with-postgresql

1 个答案:

答案 0 :(得分:2)

我想你想要一个VIEW

CREATE VIEW my_tsearch_table AS
SELECT e.id, to_tsvector(c.publicname || ' ' || string_agg(cv.name, ' '))
FROM categoryvalue cv, entitycategoryvalue c=ecv, entity e 
WHERE ccv.categoryvalueid = cv.id AND e.id = ecv.celebrityid
GROUP BY e.id;

但请注意,您无法向视图添加索引。这可能是全文搜索的问题,因为为每次搜索生成所有tsvector都是非常昂贵的。

如果您需要为该表编制索引,那么您正在寻找materialized view

PostgreSQL不支持自动维护的物化视图;你不能只是CREATE MATERIALIZED VIEW然后添加一些索引。

可以做的是使用普通表,使用查询创建的普通view以及一些触发函数手动维护物化视图。

在每个有助于视图的表上添加触发器函数,并根据对该表所做的更新,使该触发器函数更新(或根据需要插入或删除)实体化视图。但是,如果在并发环境中正确使用它可能会很复杂,并且它可能容易锁定命令死锁。

触发器维护视图的替代方法是使实体化视图过时。定期创建一个新表,将普通视图复制到新表中,添加所需的索引,然后删除旧的物化视图表并重命名新表以替换它。

另见: