微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用排序方式在 SQL 查询中实现 GraphQL 游标

如何解决如何使用排序方式在 SQL 查询中实现 GraphQL 游标

我有一个带有 reviewsid数据库rating,其中 id 是自动递增的,而 rating 是 0 到 100 之间的整数。

我正在尝试在 GraphQL API 中创建基于游标的分页,但正在努力为 hasPrevIoUsPagehasNextPage 创建必要的查询

这是我的数据:

ID: 1,rating: 50
ID: 2,rating: 80
ID: 3,rating: 20
ID: 4,rating: 40
ID: 5,rating: 60

以下是 GQL 查询的示例:

reviews(first: 3)

哪个返回

ID: 1,rating: 20

带有页面信息

hasPrevIoUsPage: false
hasNextPage: true

对 pageInfo 的查询将是

hasPrevIoUsPage = SELECT COUNT(*) > 0 FROM reviews WHERE id < 0;
hasNextPage     = SELECT COUNT(*) > 0 FROM reviews WHERE id > 3;

按评分排序时出现了我的问题。 进行类似于之前的查询

reviews(sort: "rating",first: 3)

哪个返回

ID: 3,rating: 40
ID: 1,rating: 50

带有页面信息

hasPrevIoUsPage: false
hasNextPage: true

但是我如何像以前那样为 hasPrevIoUsPagehasNextPage 创建查询

hasPrevIoUsPage = SELECT COUNT(*) > 0 FROM reviews WHERE ???
hasNextPage     = SELECT COUNT(*) > 0 FROM reviews WHERE ???

在这种情况下,WHERE 子句应该是什么?查询是否需要使用子查询复杂得多?我不确定我错过了什么。

解决方法

您实际上不需要对 hasPreviousPagehasNextPage 进行任何数据库查询。 您需要应用 +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")

您要做的是查询前 5 条评论:

SELECT *
FROM reviews
WHERE id >= ?
ORDER BY ? ASC;

-- result: 12345,12346,12347,12348,12349
-- from the app return (after computing `pageInfo`): 12346,12348

如果第一个结果的 id 与游标中的 id 匹配,即 12345 表示存在上一页。 如果有前一页且返回的行数为 4 或更少,则 hasNextPage: false。 如果没有上一页且返回的行数为 4 或更多,则hasNextPage: true

在返回结果之前,请确保过滤掉与光标 ID (12345) 匹配的项目,如果有下一页,则过滤掉一个额外的项目。

请注意必须正确生成 SQL。查询将根据分页方向(beforeafter)而变化。如果您想支持范围请求,即同时提供 beforeafter 的请求,它也会变得更加复杂。

示例:

reviews(first: 3,before: "id:12345;sort_col:user_id")

这里要使用降序。 此外,您需要过滤 ids

SELECT *
FROM reviews
WHERE id <= ?
ORDER BY ? DESC
LIMIT 5;

-- result: 12345,12344,12343,12342,12341
-- from the app return (after computing `pageInfo`): 12344,12342

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。