首页 > 解决方案 > 当 GraphQL 查询只需要返回对象的某些字段时,为什么 MySQL/Sequelize 会执行全选查询?

问题描述

对于我的应用程序中的用户,我有一个像这样的简单模式:

type Query {
  users: [User!]!
}

# The User ObjectType and Sequelize model.
type User implements UserI {
  id: ID!
  userName: String!
  firstName: String!
  lastName: String!
  email: String!
  createdAt: DateTime!
  updatedAt: DateTime!
  deletedAt: DateTime!
}

我的type-graphql解析器实现了这个简单的代码来返回一个列表users

@Resolver()
class UserResolver {
  @Query(() => [User])
  async users(): Promise<User[]> {
    return User.findAll();
  }
}

当我执行这样的查询时:

{
  users {
    firstName
  }
}

我希望等效的 MySQL 查询是这样的:SELECT firstName FROM users,但是我可以看到 Sequelize 将查询记录为:

Executing (default): SELECT `id`, `userName`, `firstName`, `lastName`, `email`, `password`, `createdAt`, `updatedAt` FROM `users` AS `User` WHERE (`User`.`deletedAt` IS NULL);

现在,虽然一切正常(我可以在客户端获取所有用户及其数据),但我想知道如果 Sequelize 执行完整的属性选择,服务器端是否有任何性能影响?这是由于 Sequelize 还是仅仅由于 GraphQL 如何解析模型字段?我错过了一些选择吗?

标签: mysqlexpressgraphqlsequelize.jstypegraphql

解决方案


我错过了一些选择吗?

您需要将 GraphQL 查询(请求)翻译成正确的 SQL 查询。只是调用findAll()没有关于请求的任何信息,因此它正确地获取了完整的实体。

基本上,您需要将 GraphQL Resolve Info 解析为更易读的格式(例如使用https://www.npmjs.com/package/graphql-fields),然后select为 TypeORM 构建一个选项(例如.findAll({ select: ['id'] }))。


推荐阅读