3

我正在尝试实施某种基本的社交网络项目。它有Posts,CommentsLikes其他任何东西一样。

  • 一个帖子可以有很多评论
  • 一个帖子可以有很多赞
  • 一篇文章可以有一个作者

/posts在客户端应用程序上有一条路线。Posts它通过分页列出并显示它们的titleimageauthorName和。commentCountlikesCount

graphql查询是这样的;

query {
  posts(first: 10, after: "123456") {
    totalCount
    edges {
      node {
        id
        title
        imageUrl
        author {
          id
          username
        }
        comments {
          totalCount
        }
        likes {
          totalCount
        }
      }
    }
  }
}

我正在使用apollo-server,TypeORM和. 我用来获取每个帖子。我只是用 批处理请求,从查询中获取,将查询结果映射到每个. 你知道,最基本的用法类型。PostgreSQLdataloaderdataloaderauthorauthorIdsdataloaderauthorsPostgreSQLwhere user.id in authorIdsauthorIddataloader

但是当我尝试在 each 下查询commentsorlikes连接时post,我被卡住了。postId如果没有分页,我可以使用相同的技术并为它们使用。但是现在我必须包含分页的过滤器参数。对于某些where条件,可能还有其他过滤器参数。

我找到了数据加载器的cacheKeyFn选项。我只是为传递给数据加载器的过滤器对象创建一个字符串键,它不会复制它们。它只是将唯一的传递给batchFn. 但是我不能创建一个 sql 查询TypeORM来分别获取每个first, after,orderBy参数的结果并将结果映射回调用数据加载器的函数。

我搜索了spectrum.chat源代码,我认为它们不允许用户查询嵌套连接。还尝试了 Github GraphQL Explorer,它可以让您查询嵌套连接。

有没有推荐的方法来实现这一目标?我了解如何使用 传递objecttodataloader和批处理它们cacheKeyFn,但我不知道如何从PostgreSQL一个查询中获取结果并将结果映射到从加载程序返回。

谢谢!

4

1 回答 1

1

所以,如果你稍微限制一下,这是可行的。限制是只允许在结果的第一页上进行批处理连接,例如,您并行获取的所有连接都是使用参数完成的。这是一个合理的约束,因为它允许您执行诸如获取前 10 个提要项和每个项的前 3 条评论之类的操作,这代表了一个相当典型的用例。尝试在单个查询中支持独立分页不太可能满足 UI 的任何实际用例,因此它可能是过度优化。考虑到这一点,您可以支持 PostgreSQL 使用 window.

这有点繁琐,但有一些答案可以让你朝着正确的方向前进:PostgreSQL 中的分组限制:显示每个组的前 N ​​行?

所以使用 dateloader 你是如何使用的cacheKeyFn,并让你的 loader 函数识别你是否可以执行优化(例如 after isnull和所有其他参数都相同)。如果可以优化,请使用窗口查询,否则像往常一样并行执行未优化的查询。

于 2020-02-16T01:45:02.523 回答