PostgreSQL 全文搜索 搜索结果排名
1 背景知识
PostgreSQL 按照 相似度
进行排序。排序的方法如下:
(1)词位频率
:查询词在文档中出现频率。
(2)词位相似
:查询词在文档中的词的相似度。
(3)词位权重
:查询词出现的文档部分权重,并按照权重排序。
PostgreSQL提供了两种预定义的排名函数。
1.1 ts_rank函数
基于文档 匹配词位
的 频率
进行排序。
ts_rank([ weights float4[], ] vector tsvector, query tsquery [, normalization integer ]) returns float4
1.2 ts_rank_cd 函数
类似于 ts_rank
函数,额外的还会匹配词位相似
度。
ts_rank_cd([ weights float4[], ] vector tsvector, query tsquery [, normalization integer ]) returns float4
1.3 按照权重值排名
对这两个函数, weights
参数可以为词位标记的权重。指定单词的是否重要,按照如下的顺序:
{D-weight, C-weight, B-weight, A-weight}
例如:{1.0,2.0,3.0,4.0}
如果未填写 weights
参数,那么将使用默认值。
{0.1, 0.2, 0.4, 1.0}
1.4 根据文档的长度排名
因为文档越长包含 查询
的可能性将会越大,所以 排名
时需要考虑文档长度。例如
(1)A文档共100个词,匹配 查询
5次。
(2)B文档共1000个词,匹配 查询
也是5次。由于 B 文档比 A 文档更长,所以 A 文档的排名更靠前。
两个排名函数都采用一个整数 normalization
选项,指定文档长度是否参与到结果的排名顺序。此选项有下列多重含义:
- doc_length : 文档长度。
- doc_length_avg: 文档平均长度。
- unique_count: 文档中唯一词的数量。
- rank: 排名的位数
参数 | 说明 |
---|---|
0 | 默认值,忽略长度的影响。 |
1 | log(rank/1 + doc_length) |
2 | rank / 1+ doc_length |
4 | rank/ doc_length_avg (只能用于 ts_rank_cd函数)。 |
8 | rank/unique_count |
16 | log(rank/1+ unique_count) |
32 | rank/rank +1 |
由于此选项是一个位掩码配置:你可以使用 |
指定一个或多个行为(例如,2|4
)。
2 根据相似度排名
SELECT title ,ts_rank(fulltext, to_tsquery('english', 'Woman')) AS rank
FROM film
WHERE fulltext @@ to_tsquery('english', 'Woman')
ORDER BY rank DESC;
LIMIT 10;
//屏幕输出:
title | rank
------------------------+-------------
MATRIX SNOWMAN | 0.075990885
HYDE DOCTOR | 0.075990885
STRANGER STRANGERS | 0.075990885
PLATOON INSTINCT | 0.075990885
TEMPLE ATTRACTION | 0.075990885
GLORY TRACY | 0.075990885
NOTORIOUS REUNION | 0.06079271
PACKER MADIGAN | 0.06079271
HUMAN GRAFFITI | 0.06079271
VANISHING ROCKY | 0.06079271
MULAN MOON | 0.06079271
ARSENIC INDEPENDENCE | 0.06079271
NOTTING SPEAKEASY | 0.06079271
OKLAHOMA JUMANJI | 0.06079271
NORTH TEQUILA | 0.06079271
MILLION ACE | 0.06079271
ANTITRUST TOMATOES | 0.0607927
SELECT title ,ts_rank_cd(fulltext, to_tsquery('english', 'Woman')) AS rank
FROM film
WHERE fulltext @@ to_tsquery('english', 'Woman')
ORDER BY rank DESC;
LIMIT 10;
//屏幕输出:
title | rank
------------------------+------
MATRIX SNOWMAN | 0.2
HYDE DOCTOR | 0.2
STRANGER STRANGERS | 0.2
PLATOON INSTINCT | 0.2
TEMPLE ATTRACTION | 0.2
GLORY TRACY | 0.2
NOTORIOUS REUNION | 0.1
PACKER MADIGAN | 0.1
HUMAN GRAFFITI | 0.1
VANISHING ROCKY | 0.1
MULAN MOON | 0.1
ARSENIC INDEPENDENCE | 0.1
3 根据文档的长度排名
SELECT title, ts_rank_cd(fulltext, to_tsquery('english', 'Woman'), 32 /* rank/(rank+1) */ ) AS rank
FROM film
WHERE to_tsquery('english', 'Woman') @@ fulltext
ORDER BY rank DESC
LIMIT 10;
title | rank
-----------------------+------------
HYDE DOCTOR | 0.16666667
PLATOON INSTINCT | 0.16666667
STRANGER STRANGERS | 0.16666667
GLORY TRACY | 0.16666667
TEMPLE ATTRACTION | 0.16666667
MATRIX SNOWMAN | 0.16666667
NOTORIOUS REUNION | 0.09090909
WAIT CIDER | 0.09090909
CREATURES SHAKESPEARE | 0.09090909
VANISHING ROCKY | 0.09090909
(10 rows)