我正在试着弄清楚这件事。
我想要从我的数据库中获取所有用户,缓存它们,然后在发出新请求时,我想获取已缓存的用户+已创建的新用户。
到目前为止:
const batchUsers = async ({ user }) => {
const users = await user.findAll({});
return users;
};
const apolloServer = new ApolloServer({
schema,
playground: true,
context: {
userLoader: new DataLoader(() => batchUsers(db)),// not sending keys since Im after all users
},
});我的解析器:
users: async (obj, args, context, info) => {
return context.userLoader.load();
}load方法需要一个参数,但在本例中,我不想有一个特定的用户,我想要所有的用户。
我不明白如何实现这一点,有人能解释一下吗?
发布于 2020-04-17 03:00:57
如果您只想加载所有记录,那么开始使用DataLoader就没有什么意义了。DataLoader背后的目的是将多个调用(如load(7)和load(22) )批处理到单个调用中,然后对数据源执行该调用。如果您需要获取所有用户,那么您应该直接调用user.findAll。
此外,如果您最终使用的是DataLoader,请确保传入的是函数,而不是对象作为上下文。该函数将在每个请求上运行,这将确保您使用的是新的DataLoader实例,而不是具有陈旧缓存的实例。
context: () => ({
userLoader: new DataLoader(async (ids) => {
const users = await User.findAll({
where: { id: ids }
})
// Note that we need to map over the original ids instead of
// just returning the results of User.findAll because the
// length of the returned array needs to match the length of the ids
return ids.map(id => users.find(user => user.id === id) || null)
}),
}),请注意,如果您希望load拒绝,您也可以在数组中返回错误的实例,而不是null。
发布于 2020-04-17 06:54:19
我花了一段时间,但我做到了:
const batchUsers = async (keys, { user }) => {
const users = await user.findAll({
raw: true,
where: {
Id: {
// @ts-ignore
// eslint-disable-next-line no-undef
[op.in]: keys,
},
},
});
const gs = _.groupBy(users, 'Id');
return keys.map(k => gs[k] || []);
};
const apolloServer = new ApolloServer({
schema,
playground: true,
context: () => ({
userLoader: new DataLoader(keys => batchUsers(keys, db)),
}),
});解析器:
user: {
myUsers: ({ Id }, args, { userLoader }) => {
return userLoader.load(Id);
},
},游乐场:
{users
{Id
myUsers
{Id}}
}游乐场解释:
users基本上获取所有用户,然后myusers通过继承第一个调用的id来做同样的事情。
我想我在这里选择了一个可怕的例子,因为我没有看到这样做会带来任何性能上的提升。但是,我确实看到查询变成了:
SELECT ... FROM User WhERE ID IN(...)https://stackoverflow.com/questions/61256372
复制相似问题