1

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

我编写了一个查询,它将给定实体的所有标签名称分组并将它们连接成一个字符串,然后我将其转换为一个 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中记录了我的最终解决方案和系统

4

1 回答 1

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为每次搜索生成所有这些 s 非常昂贵。

如果您需要索引该表,您正在寻找物化视图

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

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

在对视图有贡献的每个表上添加一个触发器函数,并让该触发器函数根据对该表所做的更新来更新(或插入或删除,视情况而定)物化视图。但是,这在并发环境中可能会很复杂,并且很容易出现锁排序死锁。

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

也可以看看:

于 2012-11-08T01:55:04.027 回答