VastbaseG100

基于openGauss内核开发的企业级关系型数据库。

Menu

附加功能

处理tsvector

Vastbase提供了用来操作tsvector类型的函数和操作符。

  • tsvector || tsvector

    tsvector连接操作符返回一个新的tsvector类型,它综合了两个tsvector中词素和位置信息,并保留词素的位置信息和权重标签。右侧的tsvector的起始位置位于左侧tsvector的最后位置,因此,新生成的tsvector几乎等同于将两个原始文档字串连接后进行to_tsvector操作。(这个等价是不准确的,因为任何从左边tsvector中删除的停用词都不会影响结果,但是,在使用文本连接时,则会影响词素在右侧tsvector中的位置。)

    相较于对文本进行连接后再执行to_tsvector操作,使用tsvector类型进行连接操作的优势在于,可以对文档的不同部分使用不同配置进行解析。因为setweight函数会对给定的tsvector中的语素进行统一设置,如果想要对文档的不同部分设置不同的权重,需要在连接之前对文本进行解析和权重设置。

  • setweight(vector tsvector, weight “char”) returns tsvector

    setweight返回一个输入tsvector的副本,其中每一个位置都使用给定的权重做了标记。权值可以为A、B、C或D(D是tsvector副本的默认权重,并且不在输出中呈现)。当对tsvector进行连接操作时,这些权重标签将会被保留,文档不同部分以不同的权重进行排序。


权重标签作用于位置,而不是词素。如果传入的tsvector已经被剥离了位置信息,那么setweight函数将什么都不做。
  • length(vector tsvector) returns integer

    返回vector中的词素的数量。

  • strip(vector tsvector) returns tsvector

    返回一个tsvector类型,其中包含输入的tsvector的同义词,但不包含任何位置和权重信息。虽然在相关性排序中,这里返回的tsvector要比未拆分的tsvector的作用小很多,但它通常都比未拆分的tsvector小的多。

处理查询

Vastbase提供了函数和操作符用来操作tsquery类型的查询。

  • tsquery && tsquery

    返回两个给定查询tsquery的与结果。

  • tsquery || tsquery

    返回两个给定查询tsquery的或结果。

  • !! tsquery

    返回给定查询tsquery的非结果。

  • numnode(query tsquery) returns integer

    返回tsquery中的节点数目(词素加操作符),这个函数在检查查询是否有效(返回值大于0),或者只包含停用词(返回值等于0)时,是有用的。例如:

    vastbase=# SELECT numnode(plainto_tsquery('the any')); 
    NOTICE:  text-search query contains only stop words or doesn't contain lexemes, ignored 
    CONTEXT:  referenced column: numnode 
    numnode  
    --------- 
       0 
     
    vastbase=# SELECT numnode('foo & bar'::tsquery); 
    numnode 
    --------- 
       3
    
  • querytree(query tsquery) returns text

    返回可用于索引搜索的tsquery部分,该函数对于检测非索引查询是有用的(例如只包含停用词或否定项)。例如:

    vastbase=# SELECT querytree(to_tsquery('!defined')); 
    querytree  
    ----------- 
    T 
    (1 row)
    

查询重写

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

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

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

    vastbase=# 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的查询范围:

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

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

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

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

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

收集文献统计

函数ts_stat可用于检查配置和查找候选停用词。

ts_stat(sqlquery text, [ weights text, ] 
        OUT word text, OUT ndoc integer, 
        OUT nentry integer) returns setof record

sqlquery是一个包含SQL查询语句的文本,该SQL查询将返回一个tsvector。ts_stat执行SQL查询语句并返回一个包含tsvector中每一个不同的语素(词)的统计信息。返回信息包括:

  • word text:词素。

  • ndoc integer:词素在文档(tsvector)中的编号。

  • nentry integer:词素出现的频率。

如果设置了权重条件,只有标记了对应权重的词素才会统计频率。例如,在一个文档集中检索使用频率最高的十个单词:

vastbase=# SELECT * FROM ts_stat('SELECT to_tsvector(''english'', sr_reason_sk) FROM tpcds.store_returns WHERE sr_customer_sk < 10') ORDER BY nentry DESC, ndoc DESC, word LIMIT 10; 
   word | ndoc | nentry  
------+------+-------- 
 32   |    2 |      2 
 33   |    2 |      2 
 1    |    1 |      1 
 10   |    1 |      1 
 13   |    1 |      1 
 14   |    1 |      1 
 15   |    1 |      1 
 17   |    1 |      1 
 20   |    1 |      1 
 22   |    1 |      1 
(10 rows)

同样的情况,但是只计算权重为A或者B的单词使用频率:

vastbase=# SELECT * FROM ts_stat('SELECT to_tsvector(''english'', sr_reason_sk) FROM tpcds.store_returns WHERE sr_customer_sk < 10', 'a') ORDER BY nentry DESC, ndoc DESC, word LIMIT 10; 
 word | ndoc | nentry  
------+------+-------- 
(0 rows)