Sql 如何实现GraphQL连接的后端?

Sql 如何实现GraphQL连接的后端?,sql,sorting,pagination,graphql,Sql,Sorting,Pagination,Graphql,在GraphQL中,分页的推荐方式是使用所述的连接。我理解这种用法的原因和优点,但我需要一个如何实现它的建议 在我的例子中,应用程序的服务器端工作在SQL数据库Postgres之上。某些GraphQL连接字段具有用于指定排序的可选参数。现在,通过了解GraphQL查询中的排序列和游标,如何构建SQL查询?当然,它应该是高效的——如果有一个SQL索引用于排序列的组合,那么应该使用它 问题是SQL不知道任何类似于GraphQL游标的东西——我们不能告诉它选择特定行之后的所有行。这里有位置、偏移和限制

在GraphQL中,分页的推荐方式是使用所述的连接。我理解这种用法的原因和优点,但我需要一个如何实现它的建议

在我的例子中,应用程序的服务器端工作在SQL数据库Postgres之上。某些GraphQL连接字段具有用于指定排序的可选参数。现在,通过了解GraphQL查询中的排序列和游标,如何构建SQL查询?当然,它应该是高效的——如果有一个SQL索引用于排序列的组合,那么应该使用它

问题是SQL不知道任何类似于GraphQL游标的东西——我们不能告诉它选择特定行之后的所有行。这里有位置、偏移和限制。在我看来,似乎我需要首先基于游标选择一行,然后使用该行中排序列的值构建第二个SQL查询,以指定一个复杂的WHERE子句——不确定数据库在这种情况下是否会使用索引

让我烦恼的是,我找不到任何关于这个话题的文章。这是否意味着在实现GraphQL服务器时通常不使用SQL数据库?那么应该使用什么数据库呢?连接字段的GraphQL查询通常如何转换为基础数据库的查询


编辑:或多或少是我自己想出来的。问题是如何扩展它以支持排序,以及如何使用数据库索引高效地实现它。

这里的技巧是,作为服务器实现者,游标可以是您想要编码为字符串的任何值。我看到的大多数示例都是base64编码的,有点不透明,但不一定要这样。例如,尝试对链接中星球大战示例中的光标进行base64解码

假设您的GraphQL模式如下所示

枚举内容列{FOO BAR} 输入滤波{ foo:Int 酒吧:Int } 类型查询{ 东西 过滤器:ThingFilter, 排序:ThingColumn, 第一:Int,, 之后:字符串 :ThingConnection } 您的第一个查询可能是

质疑{ thingsfilter:{foo:1},排序:BAR,第一个:2{ 边缘{ 节点{bar} } 页面信息{ 结束光标 下一页 } } } 这本身就可以相当直接地转换为SQL查询,如

从foo=1的物品中选择bar,按bar ASC LIMIT 2排序; 现在,当您遍历每个项目时,您可以使用其偏移量的字符串版本作为光标;这完全是规范允许的

{ 数据:{ 事情:{ 边缘:[ {节点:{bar:17}}, {节点:{bar:42}} ], 页面信息:{ 结束光标:2, hasNextPage:对 } } } } 然后,当下一个查询显示after:2时,可以将其转换回SQL偏移量并重复该查询

如果您试图构建一个通用的GraphQL接口,将其转换为合理的通用SQL查询,那么不可能创建索引以使每个查询都很快。和其他情况一样,您需要找出常见和/或慢速查询是什么,并根据需要创建索引。您可以将模式中的选项限制为您知道可以索引的内容:

其他类型{ thingsfirst:Int,after:String:ThingConnection } 查询其他事物$id:id$游标:字符串{ nodeid:$id{ …另一方面{ thingsfirst:100,后面:$cursor{…fromOver} } } } 从other_id=?按id限制订购?; 在其他id上创建索引;
对不起,这实际上是一个非常糟糕的答案。使用连接和游标的原因是为了防止基于偏移量的分页的缺点,因此使用偏移量作为游标完全否定该点。阅读本文了解详细信息:阅读如果您有一个普通的SQL数据存储,您会在游标中编码什么?我不会试图在多个HTTP事务中打开一个客户端游标对象,如果不这样做,您不是被迫重复查询并获得可能不同的答案吗?游标通常是实体的编码ID。由于我还没有联系方面的经验,我不知道那里还能用什么。但是从我读到的内容来看,建议游标不要依赖于其他参数,比如排序和条件——每个节点应该始终具有相同的游标。我想这几乎迫使光标是ID。重复查询是客户端的责任,而不是服务器的责任。我希望游标值在对同一查询的重复调用中保持一致,但我不一定希望它在不同查询中保持一致。但对它们的格式保持沉默。允许但不需要节点ID;使用节点ID作为游标但在其他字段上排序的SQL查询将是这个问题的一个很好的补充答案。