node.js - GraphQL 数据加载器与 Mongoose 填充

标签 node.js express mongoose graphql

为了执行类似连接的操作,我们可以同时使用 GraphQL 和 Mongoose 来实现这一目标。

在问任何问题之前,我想给出以下任务/事件示例(此代码均未经过测试,只是为了示例而给出):

Task {
  _id,
  title,
  description,
  activities: [{ //Of Activity Type
    _id,
    title
  }]
}

在 mongoose 中,我们可以使用 populate 检索与任务相关的事件。方法,像这样:

const task = await TaskModel.findbyId(taskId).populate('activities');

使用 GraphQL 和 Dataloader,我们可以获得相同的结果:

const DataLoader = require('dataloader');
const getActivitiesByTask = (taskId) => await ActivityModel.find({task: taskId});
const dataloaders = () => ({
    activitiesByTask: new DataLoader(getActivitiesByTask),
});
// ...
// SET The dataloader in the context
// ...

//------------------------------------------
// In another file
const resolvers = {
    Query: {
        Task: (_, { id }) => await TaskModel.findbyId(id),
    },
    Task: {
        activities: (task, _, context) => context.dataloaders.activitiesByTask.load(task._id),
    },
};

我试图查看是否有任何文章说明哪种方法在性能、资源耗尽等方面更好,但我没有找到这两种方法的任何比较。

任何见解都会有所帮助,谢谢!

最佳答案

重要的是要注意数据加载器不仅仅是数据模型的接口(interface)。虽然数据加载器被吹捧为“针对各种远程数据源的简化且一致的 API”——它们与 GraphQL 结合使用时的主要好处在于能够在单个请求的上下文中实现缓存和批处理。这种功能在处理潜在冗余数据的 API 中很重要(想想查询用户和每个用户的 friend ——很有可能多次重新获取同一用户)。

另一方面,mongoose 的populate 方法实际上只是聚合多个MongoDB 请求的一种方式。从这个意义上说,比较两者就像比较苹果和橙子。

更公平的比较可能是使用 populate 如您的问题所示,而不是按照以下行为 activities 添加解析器:

activities: (task, _, context) => Activity.find().where('id').in(task.activities)

无论哪种方式,问题都归结为您是在父解析器中加载所有数据,还是让解析器进一步向下做一些工作。 因为仅针对请求中包含的字段调用解析器,所以这两种方法之间可能会对性能产生重大影响。

如果请求 activities 字段,两种方法将在服务器和数据库之间进行相同次数的往返——性能差异可能很小。但是,您的请求可能根本不包含 activities 字段。在这种情况下,永远不会调用 activities 解析器,我们可以通过创建一个单独的 activities 解析器并在那里完成工作来保存一个或多个数据库请求。

在相关说明中...

据我所知,在 MongoDB 中使用 $lookup 之类的方法聚合查询通常比仅使用 populate 的性能要差(关于这一点的一些对话可以在 here 中找到) .然而,在关系数据库的上下文中,在考虑上述方法时还需要考虑其他注意事项。那是因为您在父解析器中的初始提取可以使用连接来完成,这通常比发出单独的数据库请求要快得多。这意味着以降低无事件字段查询的速度为代价,您可以使其他查询显着加快。

关于node.js - GraphQL 数据加载器与 Mongoose 填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52668154/

相关文章:

node.js - Mongoose 模式虚拟和异步等待

javascript - 计算上周的活跃用户数?

node.js - 发生故障转移时没有可用的主服务器 : MongoDB, Node.js, Mongoose

node.js - 函数外部的 Nodejs 变量值

node.js - 如何连接我的移动应用程序(用 lua 编写)和我的服务器(用 node.js 编写)?

node.js - 通过nodejs安装Express时出错

javascript - Node.js 表达嵌套路由

javascript - Import.meta.env 在生产构建 vitejs 上未定义

node.js - 在 Node 中对 mongodb 客户端 findOne() 进行排序

node.js - Mongoose 查询只保留 50 个文档