更新时间:2026-10-21 GMT+08:00
分享

排序查询结果

排序试图针对特定查询衡量文档的相关度,从而将众多的匹配文档中相关度最高的文档排在最前。GaussDB提供了两个预置的排序函数。函数考虑了词法、距离和结构信息;即考虑查询词在文档中出现的频率、紧密程度、以及出现的地方在文档中的重要性。然而,相关性的概念是模糊的,并且是跟应用强相关的。不同的应用程序可能需要额外的信息来排序,比如,文档的修改时间,内置的排序函数等。也可以开发自己的排序函数或者采用附加因素组合这些排序函数的结果来满足特定需求。

两个预置的排序函数:

1
ts_rank([ weights float4[], ] vector tsvector, query tsquery [, normalization integer ]) returns float4

ts_rank函数基于向量的匹配词位的频率来排名向量。

1
ts_rank_cd([ weights float4[], ] vector tsvector, query tsquery [, normalization integer ]) returns float4

ts_rank_cd函数为给定文档向量和查询计算覆盖密度排名,覆盖密度类似于ts_rank排名,不过它会考虑匹配词位相互之间的接近度。

该函数需要位置信息的输入。当匹配的token没有位置信息时,结果将会是零。

对于这两个函数,可选的weights参数提供给词加权重的能力,词的权重大小取决于所加的权值。权重阵列指定在排序时为每类词汇加多大的权重。

{D-weight, C-weight, B-weight, A-weight}

如果没有提供weights,则使用缺省值:{0.1, 0.2, 0.4, 1.0}。

通常的权重是用来标记文档特殊领域的词,如标题或最初的摘要,所以相对于文章主体中的词它们有着更高或更低的重要性。

由于较长的文档有更多的机会包含查询词,因此有必要考虑文档的大小。例如,包含有5个搜索词的一百字文档比包含有5个搜索词的一千字文档相关性更高。两个预置的排序函数都采用了一个整型的标准化选项来定义文档长度是否影响排序及如何影响。这个整型选项控制多个行为,所以它是一个屏蔽字:可以使用|指定一个或多个行为(例如,2|4)。

  • 0(缺省)表示:跟长度大小没有关系。
  • 1表示:排名(rank)除以(文档长度的对数+1)。
  • 2表示:排名除以文档的长度。
  • 4表示:排名除以两个扩展词间的调和平均距离。只能使用ts_rank_cd实现。
  • 8表示:排名除以文档中单独词的数量。
  • 16表示:排名除以单独词数量的对数+1。
  • 32表示:排名除以排名本身+1。

当指定多个标志位时,会按照所列的顺序依次进行转换。

需要特别注意的是,排序函数不使用任何全局信息,所以不可能产生一个某些情况下需要的1%或100%的理想标准值。标准化选项32 (rank/(rank+1))可用于所有规模的从零到一之间的排序,这只是一个表面变化,它不会影响搜索结果的排序。

下面是一个关于仅选择排名前十的匹配示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
gaussdb=# CREATE SCHEMA tsearch;
gaussdb=# CREATE TABLE tsearch.pgweb(id int, body text, title text, last_mod_date date) with(storage_type = ASTORE);
gaussdb=# INSERT INTO tsearch.pgweb VALUES(1, 'America is a rock band, formed in England in 1970 by multi-instrumentalists Dewey Bunnell, Dan Peek, and Gerry Beckley.', 'America', '2010-1-1');
gaussdb=# INSERT INTO tsearch.pgweb VALUES(2, 'England is a country that is part of the United Kingdom. It shares land borders with Scotland to the north and Wales to the west.', 'England', '2010-1-1');
gaussdb=# INSERT INTO tsearch.pgweb VALUES(3, 'Australia, officially the Commonwealth of Australia, is a country comprising the mainland of the Australian continent, the island of Tasmania, and numerous smaller islands.', 'Australia', '2010-1-1');
gaussdb=# INSERT INTO tsearch.pgweb VALUES(4, 'Japan is an island country in East Asia.', 'Japan', '2010-1-1');
gaussdb=# INSERT INTO tsearch.pgweb VALUES(5, 'Germany, officially the Federal Republic of Germany, is a sovereign state and federal parliamentary republic in central-western Europe.', 'Germany', '2010-1-1');
gaussdb=# INSERT INTO tsearch.pgweb VALUES(6, 'France, is a sovereign state comprising territory in western Europe and several overseas regions and territories.', 'France', '2010-1-1');
gaussdb=# INSERT INTO tsearch.pgweb VALUES(7, 'Italy officially the Italian Republic, is a unitary parliamentary republic in Europe.', 'Italy', '2010-1-1');
gaussdb=# INSERT INTO tsearch.pgweb VALUES(8, 'India, officially the Republic of India, is a country in South Asia.', 'India', '2010-1-1');
gaussdb=# INSERT INTO tsearch.pgweb VALUES(9, 'Brazil, officially the Federative Republic of Brazil, is the largest country in both South America and Latin America.', 'Brazil', '2010-1-1');
gaussdb=# INSERT INTO tsearch.pgweb VALUES(10, 'Canada is a country in the northern half of North America.', 'Canada', '2010-1-1');
gaussdb=# INSERT INTO tsearch.pgweb VALUES(11, 'Mexico, officially the United Mexican States, is a federal republic in the southern part of North America.', 'Mexico', '2010-1-1');

gaussdb=# SELECT id, title, ts_rank_cd(to_tsvector(body), query) AS rank 
FROM tsearch.pgweb, to_tsquery('america') query 
WHERE query @@ to_tsvector(body) 
ORDER BY rank DESC 
LIMIT 10;
 id |  title  | rank 
----+---------+------
 11 | Brazil  |   .2
  2 | America |   .1
 12 | Canada  |   .1
 13 | Mexico  |   .1
(4 rows)

使用标准化排序的相同例子:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
gaussdb=# SELECT id, title, ts_rank_cd(to_tsvector(body), query, 32 /* rank/(rank+1) */ ) AS rank 
FROM tsearch.pgweb, to_tsquery('america') query 
WHERE  query @@ to_tsvector(body) 
ORDER BY rank DESC 
LIMIT 10;
 id |  title  |   rank   
----+---------+----------
 11 | Brazil  |  .166667
  2 | America | .0909091
 12 | Canada  | .0909091
 13 | Mexico  | .0909091
(4 rows)

-- 删除表
gaussdb=# DROP TABLE tsearch.pgweb;
gaussdb=# DROP SCHEMA tsearch;

排序要遍历每个匹配的tsvector,因此资源消耗多,可能会因为I/O限制导致排序慢。

相关文档