在 GraphQL 中查询关系数据(NoSQL 与 RDS)

Querying relational data in GraphQL (NoSQL v RDS)

我正在编写一个包含具有某些明显关系的整体数据模型的应用程序。我开始使用 MongoDB 编写应用程序,但决定尝试过渡到 Postgres,因为我的数据有大量的“外键”。为简单起见,让我们考虑以下模型:

class GameBase {
  id: string
  entryIds: string[]
  submissionIds: string[]
}
class EntryBase {
  id: string
  description: string
  gameId: string
  userId: string // id of user who supplied entry
  submissionIds: string[] // submissions where entry is covered
}
class SubmissionBase {
  id: string
  url: string
  gameId: string
  userId: string // id of user who submitted
  entryIds: string[] // entries covered by submission
}

现在我明白了,如果我使用像 TypeOrm 这样的工具,我可以通过以下方式检索这些关系:

const games = await gameRepository.find({ relations: ["entryIds", "submissionIds"] });

但我不太确定这与 GraphQL 有何关系。到目前为止,我一直在做的是在我的解析器中添加 @ResolveField 并编写类似

的内容
// game.resolver.ts

@ResolveField(() => [SubmissionBase], { nullable: true })
submissions(@Parent() game: GameBase) {
  return this.submissionService.getManySubmissions(game.submissionIds)
}

并在服务中

// game.service.ts
async getManySubmissions(submissionIds: string[]): Promise<SubmissionBase[]> {
  if (!submissionIds) return []
  return await this.submissionRepository.find({
    where: {
      id: { $in: submissionIds },
    },
  })
}

所以这对我来说很有意义并且一直运行良好,我很好奇如果我切换到关系数据库是否会看到切实的 speed/performance 改进。例如,如果您在我的服务中看到的相同 .find 方法由 Postgres 而不是 MongoDB 支持,并且建立了适当的外键关系,则 可以我有理由期待速度提高? 我想我不会,因为它只是一个没有连接的简单获取。此外,虽然 submissionIds 是一个伪外键(因为 MongoDB),但它在这个设置中仍然充当一个。我想我不明白为什么 MongoDB 本质上是关系数据的错误选择,如果你可以使用 GraphQL 和 @ResolveField 之类的东西来获取你需要的任何东西。在这种情况下,由 GraphQL 支持的 RDS 的成功实施会是什么样子?

这是一个很好的问题,尽管我认为它会得到一些固执己见且不确定的答案。在与 SQL 和 NoSQL 数据库通信的多个生产 GraphQL 服务器上工作后,我的个人经验和建议是:

如果您要在 Postgres 等关系数据库上公开 GraphQL,并且您正在使用 NestJS 请不要手动编写 GraphQL 层

非常 耗时且容易出错,而且您将 运行 陷入与 N+1 和性能相关的各种问题,同时牺牲许多功能是通过首先使用 RDS 获得的(就像您正在谈论的连接)。作为曾经走过这条路的人,请不要

有大量非常强大的技术可以让您在 RDS 之上生成 GraphQL API。这些技术比解析 GraphQL AST 并将其转换为优化的单个 SQL 查询。我强烈建议您查看 Hasura and PostGraphile。这两者都会让您对自己的工作效率感到震惊。在 SQL 关系之上手动编写解析器只是浪费时间

然后可以将这些工具集成到您的 NestJS 应用程序中。如果您对 Hasura 特别感兴趣,我维护了可以帮助您的开源包 integrate it nicely with NestJS