我正在使用Apollo GraphQL和Mongoose开发后端应用程序。我有两个模型:User和Post,具有一对多关系(一个用户可以有多个post,但一个post属于一个用户)。
我想查询GraphQL模式中的user字段,通过id获取用户,沿着属于该用户的所有帖子。我还想查询Post类型中的author字段,以获取撰写该帖子的用户。
我了解到,在MongoDB中有两种方法可以连接来自不同集合的数据:在Apollo GraphQL解析器中使用parent参数,或者在MongoDB聚合中使用$lookup stage。
parent参数是一个对象,它包含从父字段上的解析程序返回的结果。parent参数可用于从父字段或类型访问数据,并将其传递给子字段或类型。例如,我可以使用它来连接mongoose模型,如下所示:
type User {
id: ID!
name: String
posts: [Post]
}
type Post {
id: ID!
title: String
author: User
}
type Query {
user(id: ID!): User
}
const resolvers = {
User: {
posts(parent, args, context) {
return context.db.Post.find({ author: parent.id });
},
},
};
字符串
$lookup阶段是一个聚合管道阶段,它执行到同一数据库中另一个集合的左外联接。$lookup阶段可用于将多个集合中的数据组合到单个结果集中。例如,我可以使用它来连接模型,如下所示:
db.posts
.aggregate([
{
$lookup: {
from: "users",
localField: "author",
foreignField: "_id",
as: "author",
},
},
])
.toArray((err, posts) => {
console.log(posts);
});
型
我不知道我的申请表要用哪一个。我想选择更高效、可伸缩和可维护的选项。
在Apollo GraphQL解析器中使用parent参数和在MongoDB聚合中使用$lookup stage来连接Mongoose模型之间的主要区别和权衡是什么?
2条答案
按热度按时间t40tm48m1#
这两种方法之间确实有一些差异需要了解
使用解析器
我发现这种方法更直观,可读性更强,因此更易于维护,特别是对于复杂的查询
但是,在处理大量数据时,它可能不是最有效的,因为它会为每个嵌套字段对数据库进行额外的调用。在处理大量复杂的嵌套查询时,这可能是一个性能瓶颈。
使用$lookup
另一方面,$lookup操作通常性能更高,因为它们使用单个数据库调用来连接和检索数据。
但是,随着查询复杂性的增加,$lookup操作可能会变得复杂,并且难以读取和维护。它可能需要更多关于MongoDB查询语言的知识,并且可能不像resolvers方法那样简单易用。写得不好的聚合会导致性能问题,所以要绝对确定你在做什么。
所以在你的例子中,我不介意使用resolver方法,即使使用aggregate更快,第一个方法也更容易阅读/改进/维护。
希望有帮助:)
snvhrwxg2#
我推荐第一种技术--它当然更干净,而且可能更快。您应该确保
author
字段已被索引--就像在rdb中索引外键一样。