Aci*_*dic 2 sql postgresql database-cursor graphql
我有一个数据库表,reviews其中id 是自动递增的,而 rating 是 0 到 100 之间的整数。idrating
我正在尝试在 GraphQL API 中创建基于游标的分页,但正在努力为hasPreviousPage和创建必要的查询hasNextPage。
这是我的数据:
ID: 1, RATING: 50
ID: 2, RATING: 80
ID: 3, RATING: 20
ID: 4, RATING: 40
ID: 5, RATING: 60
Run Code Online (Sandbox Code Playgroud)
以下是 GQL 查询的示例:
reviews(first: 3)
Run Code Online (Sandbox Code Playgroud)
哪个返回
ID: 1, RATING: 50
ID: 2, RATING: 80
ID: 3, RATING: 20
Run Code Online (Sandbox Code Playgroud)
带页面信息
hasPreviousPage: false
hasNextPage: true
Run Code Online (Sandbox Code Playgroud)
pageInfo 的查询将是
ID: 1, RATING: 50
ID: 2, RATING: 80
ID: 3, RATING: 20
ID: 4, RATING: 40
ID: 5, RATING: 60
Run Code Online (Sandbox Code Playgroud)
我的问题是按评级排序时出现的。进行与之前类似的查询:
reviews(sort: "rating", first: 3)
Run Code Online (Sandbox Code Playgroud)
哪个返回
ID: 3, RATING: 20
ID: 4, RATING: 40
ID: 1, RATING: 50
Run Code Online (Sandbox Code Playgroud)
带页面信息
hasPreviousPage: false
hasNextPage: true
Run Code Online (Sandbox Code Playgroud)
hasPreviousPage但是我怎样才能像hasNextPage以前一样创建查询呢?
reviews(first: 3)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,WHERE 子句应该是什么?查询是否需要使用子查询变得更加复杂?我不确定我错过了什么。
小智 5
您实际上不需要对hasPreviousPage和进行任何数据库查询hasNextPage。您需要应用 +2 技巧来实现此目的(假设您想hasPreviousPage在之前和之后的情况下实现)。
假设您有这样的查询:
// `after` should be URL-safe encoded
// `id` must have a monotonic sort order, a ULID is a fine choice for an id
// if ULID is not an option for some reason, chose a different column that has a monotonicity to it, e.g. `created_at`
reviews(first: 3, after: "id:12345;sort_cols:user_id")
Run Code Online (Sandbox Code Playgroud)
您想要做的是查询前 5 条评论:
// `after` should be URL-safe encoded
// `id` must have a monotonic sort order, a ULID is a fine choice for an id
// if ULID is not an option for some reason, chose a different column that has a monotonicity to it, e.g. `created_at`
reviews(first: 3, after: "id:12345;sort_cols:user_id")
Run Code Online (Sandbox Code Playgroud)
如果id第一个结果的 与光标中的 id 匹配,即12345表示有上一页。如果存在上一页并且返回的行数为 4 或更少,则hasNextPage: false. 如果没有上一页且返回行数为 4 或更多,则hasNextPage: true.
在返回结果之前,请确保过滤掉与光标 ID ( 12345) 匹配的项目以及一个额外的项目(如果有下一页)。
请注意,必须正确生成 SQL。查询将根据分页的方向(beforevs. after)而变化。如果您想支持范围请求,即同时提供before和 的请求,它也会变得更加复杂。after
例子:
reviews(first: 3, before: "id:12345;sort_col:user_id")
Run Code Online (Sandbox Code Playgroud)
这里你想使用降序。另外,您需要过滤 ids <= 光标中的 id。
SELECT *
FROM reviews
WHERE id >= ?
ORDER BY ? ASC
LIMIT 5;
-- result: 12345, 12346, 12347, 12348, 12349
-- from the app return (after computing `pageInfo`): 12346, 12347, 12348
Run Code Online (Sandbox Code Playgroud)