使用Apollo Graphql Server解决关系文档

我在Apollo graphql中具有Post Comment模型的实现,哪种模式是我想知道哪种实现是正确的?

  type Post {
    id: ID!
    title: String
    image: File
    imagePublicId: String
    comments: [Comment] # we have type for Comment in another schema file
    createdAt: String
    updatedAt: String
  }

  extend type Query {
    # Gets post by id
    getPosts(authUserId: ID!,skip: Int,limit: Int): Post
  }

我有一个解析器,它通过猫鼬的填充函数(如下所示)来解析Post类型并解析评论:

const Query = {
getPosts: async (root,{ authUserId,skip,limit },{ Post }) => {

    const allPosts = await Post.find(query)
      .populate({
        path: 'comments',options: { sort: { createdAt: 'desc' } },populate: { path: 'author' },})
      .skip(skip)
      .limit(limit)
      .sort({ createdAt: 'desc' });

    return allPosts
  }
}

在解析器中实现getPosts查询的第二种方式的可能方法是不使用猫鼬的填充函数,而通过为其编写单独的函数来手动解析它:

const Query = {
getPosts: async (root,{ Post }) => {
    const allPosts = await Post.find(query)
      .skip(skip)
      .limit(limit)
      .sort({ createdAt: 'desc' });

    return allPosts
  }
  Post: {
   comments: (root,args,ctx,info) => {
    return Comment.find({post: root._id}).exec()
   }
  }
}
tanichos 回答:使用Apollo Graphql Server解决关系文档

要视情况而定。

仅在请求解析器字段时才触发解析器。因此,如果getPosts解析器获取没有评论的帖子,而comments解析器获取每个帖子的评论,则只有{{1}字段包含在请求中。这样可以防止后端过度获取,从而提高此类请求的性能。

另一方面,通过分别查询每个帖子的评论,您将大大增加对数据库的请求数量(the n+1 problem)。我们可以通过在一个查询中获取所有帖子和所有注释来避免此问题,但是同样,我们不一定完全需要注释。

有两种方法可以解决这个难题:

  1. comments解析器中获取注释,但使用dataloader批处理数据库请求。这样,您将发出2个数据库请求,而不是n + 1个。

  2. 解析作为第四个参数传递给解析器的GraphQLResolveInfo对象,以确定是否请求了comments字段。这样,仅当实际请求了comments字段时,您才可以有条件地添加populate调用。

本文链接:https://www.f2er.com/3117680.html

大家都在问