【问题标题】:Prisma: Most performant way to query for sub relationsPrisma:查询子关系的最高效方式
【发布时间】:2021-01-06 06:55:05
【问题描述】:

我想查询帖子和每个帖子,我不只是想从当前用户那里得到。

我有 2 个解决方案,并且都在工作。但是哪一个更好呢?还是有更好的解决方案?

  1. 前端:React + ApolloClient
  2. 后端:Primsa2 + Graphql Nexus

Prisma 架构:

model Post {
  id            String         @id @default(cuid())
  likes         Like[]
}

model Like {
  id        String   @id @default(cuid())
  post      Post?    @relation(fields: [postId], references: [id])
  postId    String?
  user      User     @relation(fields: [userId], references: [id])
  userId    String
}

model User {
  id             String         @id @default(cuid())
  likes          Like[]
}

两种解决方案的查询字段相同:

export const posts = queryField('posts', {
  type: 'Post',
  list: true,
  resolve: async (_parent, args: any, { prisma, request }, info) => {
    opArgs={
    //unimportant
    }

    return prisma.post.findMany(opArgs)
  },
})
  1. 解决方案:我在使用 apollo 客户端的查询中直接使用 where 条件发出请求

前端:ApolloClient

const POSTS_USER = gql`
    query posts(
        $currentUserId: String
    ) {
        posts {
            id
            likes(where: { user: { id: { equals: $currentUserId } } }) { // where condition!
                id
            }
        }
        
    }
`;

const POSTS_NO_USER = gql`
    query posts(
        $currentUserId: String
    ) {
        posts {
            id
        }
        
    }
`;

const { data, loading } = useQuery(user? POSTS_USER: POSTS_NO_USER, {
        variables: {
            currentUserId: user ? user.id : "",
        },
});

后端 Nexus 对象:

const Post = objectType({
  name: 'Post',
  definition(t) {
    t.model.id()
    t.model.likes({
      filtering: {
        user: true,
      },
    })
  },
})
  1. 解决方案:我为 objectType Post 设置了 like 的字段条件。

前端:ApolloClient

const POSTS = gql`
    query posts {
        posts {
            id
            likes { // NO where condition!
                id
            }
        }
        
    }
`;

const { data, loading } = useQuery(POSTS);

Nexus 后端:

const Post = objectType({
  name: 'Post',
  definition(t) {
    t.model.id()
    t.model.likes()
    t.list.field('likes', {
      type: 'Like',
      list: true,
      resolve: (parent, args, { prisma, request }) => {
        const user = getUser(request, false)
        if (!user) {
          return []
        } else {
          return prisma.like.findMany({
            where: {
              postId: parent.id,
              userId: user.id,
            },
          })
        }
      },
    })
  },
})

【问题讨论】:

    标签: reactjs apollo-client nexus-prisma prisma2


    【解决方案1】:

    第一种方法更好,为什么?

    当您进行第一次查询时,prisma 将在 1 个 DB 查询中执行您的查询。 当您进行第二次查询时,您将有数据库查询,因为您有帖子编号

    使用我的PrismaSelect 插件 Prisma Select 的最佳方式是在通用 graphql 参数(父、参数、上下文、信息)中使用info: GraphQLResolveInfo 对象来选择prisma client 接受的对象。该方法可以提供更好的性能,因为您将只使用一个解析器来检索您的所有请求。通过这样做,它还消除了N + 1 问题。

    但您还需要放弃使用 nexus-plugin-prisma 并使用我的 pal.js CLI 自动生成您的 CRUD

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-03
      • 2020-04-14
      • 1970-01-01
      • 2014-01-25
      • 1970-01-01
      • 2021-01-23
      • 2016-10-19
      • 2023-01-15
      相关资源
      最近更新 更多