Apollo Server中父对象包含ID数组时如何正确使用Data Loader?
修复方案
你的代码存在3处核心问题,按下方修改即可正常运行:
1. 字段Resolver修改
你当前的parent.subCategory是ObjectId数组,直接调用toString()会把整个数组转为逗号拼接的错误字符串,且load()仅支持传入单个ID,加载多个ID需要调用loadMany()方法:
subCategory: async (parent, _, {loaders}) => { // 把数组中每个ObjectId转为字符串,批量加载 const subIds = parent.subCategory.map(id => id.toString()) return await loaders.subCategory.loadMany(subIds); }
2. 批量加载函数修改
存在变量名拼写错误、ID类型不匹配、查询效率低三个问题,修改后代码:
// 提前从mongoose/mongodb导入ObjectId const { ObjectId } = require('mongoose').Types; module.exports.batchSubCategory = async (categoryIds) => { // 修正变量名错误,将查询ID转为ObjectId匹配MongoDB存储格式 const subcategories = await Subcategory.find({_id: {$in: categoryIds.map(id => new ObjectId(id))}}); // 建立ID映射表,保证返回顺序和传入ID顺序完全一致(Dataloader强制要求) const subMap = new Map(subcategories.map(item => [item._id.toString(), item])); return categoryIds.map(id => subMap.get(id) || null); }
3. Context配置优化
简化多余的函数包裹,确保依赖导入正确:
// 提前导入依赖 const Dataloader = require('dataloader'); const { batchSubCategory } = require('./你的加载函数文件路径'); context: async ({req}) => { return { loaders: { subCategory: new Dataloader(batchSubCategory) } } },
额外注意事项
- 确保你的GraphQL Schema中Category类型的subCategory字段定义为数组类型:
subCategory: [SubCategory] - 不要把Dataloader实例定义为全局变量,当前每次请求在context中新建实例的写法是正确的,避免跨请求缓存污染
内容的提问来源于stack exchange,提问作者user17578307
相关产品推荐
相关产品推荐

