使用 GraphQL、Nexus 和 Prisma 优化 SQL 查询

Posted

技术标签:

【中文标题】使用 GraphQL、Nexus 和 Prisma 优化 SQL 查询【英文标题】:Optimize SQL queries using GraphQL, Nexus and Prisma 【发布时间】:2021-08-30 16:24:52 【问题描述】:

我正在尝试对包含关系的 GraphQL 查询应用一些 SQL 优化。我使用 Prisma (v. 2.24.1)、Nexus (v. 1.0.0)、nexus-plugin-prisma (v. 0.35.0) 和 graphql (v. 15.5.0)。

schema.prisma:


model User 
  id             Int           @id @default(autoincrement())
  username       String
  firstName      String?
  lastName       String?
  password       String
  email          String
  organization   Organization  @relation(fields: [organizatonId], references: [id])
  organizatonId  Int


model Organization 
  id        Int     @id @default(autoincrement())
  name      String  @unique
  users     User[]

当我尝试执行一个简单的 GraphQL 查询时,该查询会使用用户获取当前组织,prisma 会生成一个 SQL 查询,该查询会询问所有用户的列,即使我只询问 ID。

查询:


  organization 
    id
    name
    users 
      id
    
  

sql:

SELECT "public"."Organization"."id", "public"."Organization"."name" FROM "public"."Organization" WHERE 1=1 LIMIT $1 OFFSET $2
SELECT "public"."Organization"."id" FROM "public"."Organization" WHERE "public"."Organization"."id" = $1 LIMIT $2 OFFSET $3
SELECT "public"."User"."id", "public"."User"."username", "public"."User"."firstName", "public"."User"."lastName", "public"."User"."password", "public"."User"."email", "public"."User"."organizatonId" FROM "public"."User" WHERE "public"."User"."organizatonId" IN ($1) OFFSET $2

对于解析器,我使用t.model 语法:

import  objectType  from "nexus"

export const Organization = objectType(
  name: 'Organization',
  definition(t) 
    t.model.id()
    t.model.name()
    t.model.users()
  
)

就目前而言,我发现当使用 t.list.field 语法和 resolve 函数时,我可以从 info 参数中获取请求的用户字段,但似乎没有优雅的方式来传递它数据到 prisma 客户端。

t.list.field('users', 
  type: 'User',
  resolve(org, args, ctx, info) 
    // info contains the requested fields
    return ctx.prisma.organization.findUnique(
       where:  id: org.id 
    ).users()
  
)

有没有办法使用来自info 的数据并只查询user.id 字段?

【问题讨论】:

【参考方案1】:

您可以使用一个社区制作的插件来处理所有繁重的工作:https://paljs.com/plugins/select/

【讨论】:

以上是关于使用 GraphQL、Nexus 和 Prisma 优化 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

使用 nexus-prisma graphql 处理文件上传

Nexus GraphQL Prisma 事件字段

如何使用 prisma 2 或 3 和 nexus 模式生成同时生成生成的 crud 和“ondelete 级联”

Prisma nexus crud 未正确生成模式

如何将数组作为参数传递给 Nexus?如何使用 Prisma 从这个数组创建多个对象?

仅使用 prisma 和 nexus 检索所有者数据的可能性