ts_rewrite 函数族可以从tsquery 中搜索一个特定的目标子查询,并在该子查询每次出现 的地方都替换为另一个子查询。实际上这只是通过字串替换而得到的一个特定tsquery 版 本。 目标子查询和替换查询组合起来可以被认为是一个重写规则。 一组类似的重写规则可以 为搜索提供强大的帮助。 例如, 可以使用同义词扩大搜索范围 (例如, new york, big apple, nyc, gotham)或限制搜索范围在用户直接感兴趣的热点话题上。 ts_rewrite (query tsquery, target tsquery, substitute tsquery) returns tsquery ts_rewrite 的这种形式只适用于一个单一的重写规则:任何出现目标子查询的地方都被 无条件替换。例如: gbase=#SELECT ts_rewrite('a & b'::tsquery, 'a'::tsquery, 'c'::tsquery); ts_rewrite ------------ 'b' & 'c' ts_rewrite (query tsquery, select text) returns tsquery ts_rewrite 的这种形式接受一个起始查询和SQL 查询命令。这里的查询命令是文本字 串形式,必须产生两个tsquery 列。查询结果的每一行,第一个字段的值(目标子查询)都 会被第二个字段(替代子查询)替换。 当多个规则需要重写时,重写顺序非常重要;因此在实践中需要使用ORDER BY 将源查询按照某些字段进行排序。 例如:举一个现实生活中天文学上的例子。我们将使用表驱动的重写规则扩大 GBase 8c SQL 参考手册 南大通用数据技术股份有限公司 645 supernovae 的查询范围: gbase=#CREATE TABLE tsearch.aliases (id int, t tsquery, s tsquery); gbase=#INSERT INTO tsearch.aliases VALUES(1, to_tsquery('supernovae'), to_tsquery('supernovae|sn')); gbase=#SELECT ts_rewrite(to_tsquery('supernovae & crab'), 'SELECT t, s FROM tsearch.aliases'); ts_rewrite --------------------------------- 'crab' & ( 'supernova' | 'sn' ) 可以通过更新表修改重写规则: gbase=#UPDATE tsearch.aliases SET s = to_tsquery('supernovae|sn & !nebulae') WHERE t = to_tsquery('supernovae'); gbase=#SELECT ts_rewrite(to_tsquery('supernovae & crab'), 'SELECT t, s FROM tsearch.aliases'); ts_rewrite --------------------------------------------- 'crab' & ( 'supernova' | 'sn' & !'nebula' ) 需要重写的规则越多,重写操作就越慢。 因为它要检查每一个可能匹配的规则。为了过 滤明显的非候选规则,可以使用tsquery 类型的操作符来实现。在下面的例子中,我们只选 择那些可能与原始查询匹配的规则: gbase=#SELECT ts_rewrite('a & b'::tsquery, 'SELECT t,s FROM tsearch.aliases WHERE ''a & b''::tsquery @> t'); ts_rewrite ------------ 'b' & 'a' (1 row) gbase=#DROP TABLE tsearch.aliases;