排序查询结果

    两个预置的排序函数:

    基于词素匹配率对vector进行排序:

    该函数需要位置信息的输入。因此它不能在“剥离”tsvector值的情况下运行—它将总是返回零。

    如果没有提供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. openGauss=# SELECT id, title, ts_rank_cd(to_tsvector(body), query) AS rank
    2. FROM tsearch.pgweb, to_tsquery('america') query
    3. WHERE query @@ to_tsvector(body)
    4. ORDER BY rank DESC
    5. id | title | rank
    6. ----+---------+------
    7. 11 | Brazil | .2
    8. 2 | America | .1
    9. 13 | Mexico | .1
    10. (4 rows)

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

    1. openGauss=# CREATE TABLE tsearch.ts_ngram(id int, body text);
    2. openGauss=# INSERT INTO tsearch.ts_ngram VALUES(1, '中文');
    3. openGauss=# INSERT INTO tsearch.ts_ngram VALUES(2, '中文检索');
    4. openGauss=# INSERT INTO tsearch.ts_ngram VALUES(3, '检索中文');
    5. --精确匹配
    6. id | body | rank
    7. 1 | 中文 | .1
    8. (1 row)
    9. --模糊匹配
    10. openGauss=# SELECT id, body, ts_rank_cd(to_tsvector('ngram',body), query) AS rank FROM tsearch.ts_ngram, to_tsquery('中文') query WHERE query @@ to_tsvector('ngram',body);
    11. id | body | rank
    12. ----+----------+------
    13. 3 | 检索中文 | .1
    14. 1 | 中文 | .1

    排序要遍历每个匹配的tsvector,因此资源消耗多,可能会因为I/O限制导致排序慢。可是这是很难避免的,因为实际查询中通常会有大量的匹配。