文本搜索附加功能

文本搜索附加功能

Greenplum数据库具有其他附加功能和操作符,您可以使用它们来操作搜索和查询向量,以及重写搜索查询。

本节包含以下子主题:

操纵文档

解析文件显示了如何将原始文本文档转换为tsvector值。 Greenplum数据库还提供了可用于处理已经处于tsvector形式的文档的函数和运算符。

tsvector || tsvector

tsvector连接运算符返回一个向量,该向量合并了作为参数给出的两个向量的词位和位置信息。 在连接期间保留位置和重量标签。 出现在右侧向量中的位置按左侧向量中提到的最大位置偏移,因此结果几乎等于在两个原始文档字符串的串联上执行to_tsvector的结果。 (等价不精确,因为从左手参数末尾删除的任何停止词都不会影响结果,而如果使用文本连接,它们会影响右手参数中词位的位置。)

在向量形式中使用连接的一个优点是,您可以使用不同的配置来解析文档的不同部分,而不是在应用to_tsvector之前连接文本。 此外,因为setweight函数以相同的方式标记给定向量的所有词位,所以如果要使用不同的权重标记文档的不同部分,则必须在连接之前解析文本并执行setweight

setweight(vector tsvector, weight "char") returns tsvector

setweight返回输入向量的副本,其中每个位置都标有给定的权重,A, B, C, 或D。 (D是新向量的默认值,因此不会在输出中显示。) 这些标签在连接向量时保留,允许来自文档的不同部分的单词通过排名函数被不同地加权。

请注意,重量标签适用于位置,而不是词位。 如果输入向量已被剥离,则setweight不执行任何操作。

length(vector tsvector) returns integer

返回向量中存储的词位数。

strip(vector tsvector) returns tsvector

返回一个向量,该向量列出与给定向量相同的词位,但缺少任何位置或权重信息。 虽然返回的向量比未被剥离的向量用于相关性排名要小得多,但它通常会小得多。

操纵查询

解析查询显示了如何将原始文本查询转换为tsquery值。 Greenplum数据库还提供了可用于操作已经处于tsquery形式的查询的函数和运算符。

tsquery && tsquery

返回两个给定查询的AND组合。

tsquery || tsquery

返回两个给定查询的OR组合。

!! tsquery

返回给定查询的非(NOT)。

numnode(query tsquery) returns integer

返回tsquery中的节点数(词位加运算符)。 此函数可用于确定查询是否有意义(返回> 0),或仅包含停止词(返回0)。 例子:

SELECT numnode(plainto_tsquery('the any'));
NOTICE:  query contains only stopword(s) or doesn't contain lexeme(s), ignored
 numnode
---------
       0

SELECT numnode('foo & bar'::tsquery);
 numnode
---------
       3
querytree(query tsquery) returns text

返回可用于搜索索引的tsquery部分。 此函数对于检测不可索引的查询很有用,例如那些仅包含停止词或仅包含否定词的查询。 例如:

SELECT querytree(to_tsquery('!defined'));
 querytree
-----------

重写查询

ts_rewrite系列函数在给定的tsquery中搜索目标子查询的出现,并在每次出现替换子查询。 实质上,此操作是子串替换的特定于tsquery的版本。 目标和替代组合可以被认为是查询重写规则。 这种重写规则的集合可以是强大的搜索辅助工具。 例如,您可以使用同义词(例如,new york, big apple, nyc, gotham)扩展搜索范围,或者缩小搜索范围以引导用户查看某些热门话题。 此功能与同义词词典(同义词词典)之间在功能上存在一些重叠。 但是,您可以在不重建索引的情况下即时修改一组重写规则,而更新同义词库则需要重建索引才能生效。

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

这种形式的ts_rewrite只应用一个重写规则:target在查询中出现的任何地方都被substitute替换。 例如:

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 select命令,它以文本字符串形式给出。 select必须产生两列tsquery类型。 对于select结果的每一行,第一列值(target)的出现被当前查询值中的第二列值(substitute)替换。 例如:

CREATE TABLE aliases (id int, t tsquery, s tsquery);
INSERT INTO aliases VALUES('a', 'c');

SELECT ts_rewrite('a & b'::tsquery, 'SELECT t,s FROM aliases');
 ts_rewrite
------------
 'b' & 'c'

请注意,当以这种方式应用多个重写规则时,应用程序的顺序可能很重要; 所以在实践中你会希望源查询ORDER BY一些排序键。

让我们考虑一个现实生活中的天文例子。 我们将使用表驱动的重写规则扩展查询supernovae

CREATE TABLE aliases (id int, t tsquery primary key, s tsquery);
INSERT INTO aliases VALUES(1, to_tsquery('supernovae'), to_tsquery('supernovae|sn'));

SELECT ts_rewrite(to_tsquery('supernovae & crab'), 'SELECT t, s FROM aliases');
           ts_rewrite            
---------------------------------
 'crab' & ( 'supernova' | 'sn' )

我们可以通过更新表来更改重写规则:

UPDATE aliases
SET s = to_tsquery('supernovae|sn & !nebulae')
WHERE t = to_tsquery('supernovae');

SELECT ts_rewrite(to_tsquery('supernovae & crab'), 'SELECT t, s FROM aliases');
                 ts_rewrite                  
---------------------------------------------
 'crab' & ( 'supernova' | 'sn' & !'nebula' )

当有许多重写规则时,重写可能会很慢,因为它会检查每个规则是否存在可能的匹配。 为了过滤掉明显的非候选规则,我们可以使用tsquery类型的包含运算符。 在下面的示例中,我们仅选择可能与原始查询匹配的规则:

SELECT ts_rewrite('a & b'::tsquery,
                  'SELECT t,s FROM aliases WHERE ''a & b''::tsquery @> t');
 ts_rewrite
------------
 'b' & 'c'

收集文档统计信息

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

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

sqlquery是一个包含SQL查询的文本值,该查询必须返回单个tsvector列。 ts_stat执行查询并返回有关tsvector数据中包含的每个不同词位(word)的统计信息。 返回的列是

  • word text — 词位的值
  • ndoc integer — 出现这个词的文件数量(tsvectors)
  • nentry integer — 单词出现总数

如果提供权重,则仅计算具有这些权重之一的事件。

例如,要查找文档集合中十个最常用的单词:

SELECT * FROM ts_stat('SELECT vector FROM apod')
ORDER BY nentry DESC, ndoc DESC, word
LIMIT 10;

相同,但只计算权重为AB的单词出现次数:

SELECT * FROM ts_stat('SELECT vector FROM apod', 'ab')
ORDER BY nentry DESC, ndoc DESC, word
LIMIT 10;