使用 Apollo Graphql Server 解析关系文档

Posted

技术标签:

【中文标题】使用 Apollo Graphql Server 解析关系文档【英文标题】:Resolving relational document using Apollo Graphql Server 【发布时间】:2020-03-08 03:03:31 【问题描述】:

我在 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 类型并通过 mongoose 的填充功能解析评论,如下所示:

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 查询的可能方式是不使用 mongoose 的填充函数并通过为其编写单独的函数来手动解析它:

const Query = 
getPosts: async (root,  authUserId, skip, limit ,  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()
   
  

【问题讨论】:

你不想填充,因为如果你不要求填充的数据呢?您仍在查询它并将该数据保存在内存中。在单独的解析器中处理所有人口。第二种方案是最好的 【参考方案1】:

视情况而定。

只有在请求其字段时才会触发解析器。因此,如果getPosts 解析器获取没有 cmets 的帖子,而comments 解析器获取每个帖子的 cmets,则在请求中包含 comments 字段时才获取 cmets .这可以通过防止后端过度获取来提高此类请求的性能。

另一方面,通过单独查询每个帖子的 cmets,您将大大增加对数据库的请求数量 (the n+1 problem)。我们可以通过在一个查询中获取所有帖子和所有 cmets 来避免这个问题,但同样,我们可能根本不需要 cmets。

解决这个困境有两种选择:

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

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

【讨论】:

以上是关于使用 Apollo Graphql Server 解析关系文档的主要内容,如果未能解决你的问题,请参考以下文章

使用替代 GraphQL 客户端连接到 Apollo Server

使用 ApolloClient 和 Apollo-Server-Express 处理 GraphQL 错误

如何在没有 Apollo Server 但使用 express-graphql 的情况下使用 apollo-datasource-rest

来自 GraphQL 网站的 Apollo-server 教程产生错误

如何从 Apollo Server 端点获得完整的 GraphQL 架构?

使用 Apollo Graphql Server 解析关系文档