不知怎的,我已经欺骗自己在数据库上编写全文搜索实现。我有一个代表我数据库中所有实体的表,一个表示所有标签的表,以及一个表示标签与实体的多对多关系的表。
我编写了一个查询,该查询将给定实体的所有标记名称分组,并将它们连接成一个字符串,然后我将其转换为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
答案 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以及一些触发函数手动维护物化视图。
在每个有助于视图的表上添加触发器函数,并根据对该表所做的更新,使该触发器函数更新(或根据需要插入或删除)实体化视图。但是,如果在并发环境中正确使用它可能会很复杂,并且它可能容易锁定命令死锁。
触发器维护视图的替代方法是使实体化视图过时。定期创建一个新表,将普通视图复制到新表中,添加所需的索引,然后删除旧的物化视图表并重命名新表以替换它。
另见: