文档首页 > > 开发指南> 全文检索> 附加功能> 查询重写

查询重写

分享
更新时间: 2019/11/12 GMT+08:00

ts_rewrite函数族可以从tsquery中搜索一个特定的目标子查询,并在该子查询每次出现的地方都替换为另一个子查询。 实际上这只是通过字串替换而得到的一个特定tsquery版本。目标子查询和替换查询组合起来可以被认为是一个重写规则。一组类似的重写规则可以为搜索提供强大的帮助。例如,可以使用同义词扩大搜索范围(例如,new york, big apple, nyc, gotham)或限制搜索范围在用户直接感兴趣的热点话题上。

  • ts_rewrite (query tsquery, target tsquery, substitute tsquery) returns tsquery

    ts_rewrite的这种形式只适用于一个单一的重写规则:任何出现目标子查询的地方都被无条件替换。例如:

    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将源查询按照某些字段进行排序。

    例如:举一个现实生活中天文学上的例子。我们将使用表驱动的重写规则扩大supernovae的查询范围:

    CREATE TABLE tsearch.aliases (id int, t tsquery, s tsquery);
    
    INSERT INTO tsearch.aliases VALUES(1, to_tsquery('supernovae'), to_tsquery('supernovae|sn'));
    
    SELECT ts_rewrite(to_tsquery('supernovae & crab'), 'SELECT t, s FROM tsearch.aliases');
    
               ts_rewrite            
    ---------------------------------
     'crab' & ( 'supernova' | 'sn' )

    可以通过更新表修改重写规则:

    UPDATE tsearch.aliases
    SET s = to_tsquery('supernovae|sn & !nebulae')
    WHERE t = to_tsquery('supernovae');
    
    SELECT ts_rewrite(to_tsquery('supernovae & crab'), 'SELECT t, s FROM tsearch.aliases');
    
                     ts_rewrite                  
    ---------------------------------------------
     'crab' & ( 'supernova' | 'sn' & !'nebula' )

    需要重写的规则越多,重写操作就越慢。因为它要检查每一个可能匹配的规则。为了过滤明显的非候选规则,可以使用tsquery类型的操作符来实现。在下面的例子中, 我们只选择那些可能与原始查询匹配的规则:

    SELECT ts_rewrite('a & b'::tsquery, 'SELECT t,s FROM tsearch.aliases WHERE ''a & b''::tsquery @> t');
    
     ts_rewrite 
    ------------
     'b' & 'a'
    (1 row)
    DROP TABLE ts_rewrite;
分享:

    相关文档

    相关产品

文档是否有解决您的问题?

提交成功!

非常感谢您的反馈,我们会继续努力做到更好!

反馈提交失败,请稍后再试!

*必选

请至少选择或填写一项反馈信息

字符长度不能超过200

提交反馈 取消

如您有其它疑问,您也可以通过华为云社区问答频道来与我们联系探讨

跳转到云社区