Javascript 使用Apollo Graphql服务器解析关系文档
我在Apollo graphql中实现了Post-Comment模型,我想知道哪个模式是正确的Javascript 使用Apollo Graphql服务器解析关系文档,javascript,mongoose,graphql,apollo,apollo-server,Javascript,Mongoose,Graphql,Apollo,Apollo 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: Strin
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
}
我有一个解析器,它通过mongoose的填充函数解析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查询的第二种方法是不使用mongoose的populate函数,并通过为其编写单独的函数手动进行解析:
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()
}
}
}
视情况而定
只有在请求解析程序的字段时,才会触发解析程序。因此,如果getPosts
resolver获取没有注释的帖子,而comments
resolver获取每个帖子的注释,那么只有在请求中包含comments
字段时,才会获取注释。这可以通过防止后端的过度抓取来提高此类请求的性能
另一方面,通过单独查询每篇文章的评论,您将大大增加对数据库()的请求数量。我们可以通过在一个查询中获取所有帖子和所有评论来避免这个问题,但是,同样,我们可能根本不需要这些评论
解决这一困境有两种选择:
comments
resolver中的注释,但用于批处理数据库请求。这样,您将发出2个数据库请求,而不是n+1个请求comments
字段。这样,仅当实际请求了注释
字段时,才可以有条件地添加填充
调用您不想填充,因为如果您不要求填充的数据呢?您仍在查询它&将该数据保存在内存中。在单独的解析程序中执行所有填充。第二种解决方案是最好的