首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Prisma2:如何用Paljs解决n +1问题

Prisma2:如何用Paljs解决n +1问题
EN

Stack Overflow用户
提问于 2020-10-08 00:06:28
回答 2查看 808关注 0票数 1

谢谢你的帮助。

我在前端使用阿波罗客户端,在后端使用graphql-nexus,prisma2和graphql-yoga服务器。

我想用@paljs/plugins解决n+1问题。

在前台,我有一个查询帖子,比如:

代码语言:javascript
复制
query posts{
    posts {
        id
        favoritedBy(where: { id: { equals: $currentUserId } }) {
            id
        }
        author {
            id
            avatar {
                id
            }
        }
        link {
            id
        }
        games {
            id
        }
        tags {
            id
        }
        likes(where: { user: { id: { equals: $currentUserId } } }) {
            id
        }
    }
}

帖子解析器:

代码语言:javascript
复制
import { PrismaSelect } from '@paljs/plugins'
export const posts = queryField('posts', {
  type: 'Post',
  list: true,
  args: {
    ...
  },
  resolve: async (_parent, args, { prisma, request }, info) => {
    const select = new PrismaSelect(info).value
    let opArgs: FindManyPostArgs = {
      take: 10,
      orderBy: {
        [args.orderBy]: 'desc',
      },
      ...select
    }

    const post = await prisma.post.findMany(opArgs)
    
    //The result I want to return with the "sub-models" like likes, author tags...
    console.log(JSON.stringify(post, undefined, 2))

    return post
  },
})

我记录查询

代码语言:javascript
复制
const prisma = new PrismaClient({
  log: ['query'],
})

我的问题:有了PrismaSelect,我有比没有PrismaSelect多5个查询,如果我在前端检查请求时间,我需要用300-400ms的时间。那么我做错了什么呢?我在@paljs/plugins文档中看到了上下文中的select。也许这就是我的错误。如何在上下文中使用select?

下面是我的上下文:

代码语言:javascript
复制
import { PrismaClient, PrismaClientOptions } from '@prisma/client'
import { PubSub } from 'graphql-yoga'
import { PrismaDelete, onDeleteArgs } from '@paljs/plugins'

class Prisma extends PrismaClient {
  constructor(options?: PrismaClientOptions) {
    super(options)
  }

  async onDelete(args: onDeleteArgs) {
    const prismaDelete = new PrismaDelete(this)
    await prismaDelete.onDelete(args)
  }
}

export const prisma = new PrismaClient({
  log: ['query'],
})
export const pubsub = new PubSub()

export interface Context {
  prisma: PrismaClient
  request: any
  pubsub: PubSub
}

export function createContext(request: any): Context {
  return { prisma, request, pubsub }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-10-08 01:56:54

您需要知道,要使用我的PrismaSelect插件,您需要删除nexus-prisma-plugin包,并使用我的Pal.js CLI创建用于nexus的CRUD和ObjectType,并使用@paljs/nexus插件添加mackSchema函数

代码语言:javascript
复制
import { makeSchema } from '@nexus/schema';
import * as types from './graphql';
import { paljs } from '@paljs/nexus'; // import our plugin

export const schema = makeSchema({
  types,
  plugins: [paljs()],// here our plugin don't use nexus-prisma-plugin
  outputs: {
    schema: __dirname + '/generated/schema.graphql',
    typegen: __dirname + '/generated/nexus.ts',
  },
  typegenAutoConfig: {
    sources: [
      {
        source: require.resolve('./context'),
        alias: 'Context',
      },
    ],
    contextType: 'Context.Context',
  },
});

现在将此类型添加到您的Context

代码语言:javascript
复制
export interface Context {
  prisma: PrismaClient
  request: any
  pubsub: PubSub
  select: any // here our select type
}
export function createContext(request: any): Context {
// our paljs plugin will add select object before resolver
  return { prisma, request, pubsub, select: {} }
}

添加我们的插件后,您的查询将如下所示

代码语言:javascript
复制
extendType({
  type: 'Query',
  definition(t) {
    t.field('findOneUser', {
      type: 'User',
      nullable: true,
      args: {
        where: arg({
          type: 'UserWhereUniqueInput',
          nullable: false,
        }),
      },
      resolve(_, { where }, { prisma, select }) {
// our plugin add select object into context for you
        return prisma.user.findOne({
          where,
          ...select,
        });
      },
    });
  },
});

您是否可以尝试使用我的pal c命令从我的列表中启动一个示例,并尝试您的模式并对其进行测试

票数 1
EN

Stack Overflow用户

发布于 2020-10-08 02:25:59

它正在工作,thx Ahmed你的插件真棒!

我将我的Post-Object从

代码语言:javascript
复制
const Post = objectType({
  name: 'Post',
  definition(t) {
    t.model.id()
    t.model.authorId()
    t.model.tags()
    t.model.games()
    t.model.link()
    t.model.report()
    t.model.notifications()
    t.model.author()
    t.model.favoritedBy({
      filtering: {
        id: true,
      },
    })
    t.model.likes({
      filtering: {
        user: true,
      },
    })
  }
})

代码语言:javascript
复制
const Post = objectType({
  name: 'Post',
  definition(t) {
    t.string('id')
    t.field('tags', {
      nullable: false,
      list: [true],
      type: 'Tag',
      resolve(parent: any) {
        return parent['tags']
      },
    })
    t.field('games', {
      list: [true],
      type: 'Game',
      resolve(parent: any) {
        return parent['games']
      },
    })
    t.field('link', {
      type: 'Link',
      nullable: true,
      resolve(parent: any) {
        return parent['link']
      },
    })
    t.field('notifications', {
      list: [true],
      type: 'Notification',
      resolve(parent: any) {
        return parent['notifications']
      },
    })
    t.field('author', {
      nullable: false,
      type: 'User',
      resolve(parent: any) {
        return parent['author']
      },
    })
    t.field('favoritedBy', {
      nullable: false,
      list: [true],
      type: 'User',
      args: {
        where: 'UserWhereInput',
      },
      resolve(parent: any) {
        return parent['favoritedBy']
      },
    })
    t.field('likes', {
      list: [true],
      type: 'Like',
      args: {
        where: 'LikeWhereInput',
      },
      resolve(parent: any) {
        return parent['likes']
      },
    })
  },
})

我还同时使用了plugin和paljs-plugin

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64248004

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档