我正在构建一个允许全文搜索的服务,我想对结果进行分页。
我不想使用OFFSET
,因此我选择了使用键集分页进行无限滚动,如此处所述。
我的搜索查询如下所示:
SELECT *, ts_rank_cd(t.tsv, plainto_tsquery($1)) AS rank
FROM profiles AS t, plainto_tsquery($1) AS q
WHERE (tsv @@ q) AND
(rank, n, id) < ($2, $3, $4)
ORDER BY rank DESC, n DESC, id DESC
LIMIT 50
该tsv
列包含tsvector
对象,并使用 GIN 进行索引。搜索结果首先按rank
由 PostgreSQL 计算的 排序,然后按此处不相关的另一列排序,最后按 id 排序。
这对我来说似乎是正确的,但我得到了这个错误:column "rank" does not exist
。如果我用子句rank
中的表达式替换它,它就会起作用。WHERE
这会影响性能吗?
第二个问题:如果我想排序id ASC
而不是排序,我怎样才能使键集分页工作id DESC
?我不能WHERE
像这样拆分子句中的表达式,(rank, n) < ($2, $3) AND id > $4
因为这样我就失去了排序优先级(id 只能用于打破平局)。
是的,如果没有更改,查询将不起作用。所以这是一个积极的影响,但是排名不会被计算两次,所以没有惩罚。
不过在order-by之前需要扫描全表生成rank列,所以效率和.差不多
offset
。如果是数字类型,请
-id
改用。否则你必须将元组比较扩展成一个大的混乱表达式。