首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用dataloader?

如何使用dataloader?
EN

Stack Overflow用户
提问于 2020-04-17 01:30:18
回答 2查看 448关注 0票数 1

我正在试着弄清楚这件事。

我想要从我的数据库中获取所有用户,缓存它们,然后在发出新请求时,我想获取已缓存的用户+已创建的新用户。

到目前为止:

代码语言:javascript
复制
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
  },
});

我的解析器:

代码语言:javascript
复制
    users: async (obj, args, context, info) => {
      return context.userLoader.load();
}

load方法需要一个参数,但在本例中,我不想有一个特定的用户,我想要所有的用户。

我不明白如何实现这一点,有人能解释一下吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-04-17 03:00:57

如果您只想加载所有记录,那么开始使用DataLoader就没有什么意义了。DataLoader背后的目的是将多个调用(如load(7)load(22) )批处理到单个调用中,然后对数据源执行该调用。如果您需要获取所有用户,那么您应该直接调用user.findAll

此外,如果您最终使用的是DataLoader,请确保传入的是函数,而不是对象作为上下文。该函数将在每个请求上运行,这将确保您使用的是新的DataLoader实例,而不是具有陈旧缓存的实例。

代码语言:javascript
复制
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

票数 1
EN

Stack Overflow用户

发布于 2020-04-17 06:54:19

我花了一段时间,但我做到了:

代码语言:javascript
复制
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)),
  }),
});

解析器:

代码语言:javascript
复制
  user: {
    myUsers: ({ Id }, args, { userLoader }) => {
      return userLoader.load(Id);
    },
  },

游乐场:

代码语言:javascript
复制
{users
{Id
myUsers
{Id}}
}

游乐场解释:

users基本上获取所有用户,然后myusers通过继承第一个调用的id来做同样的事情。

我想我在这里选择了一个可怕的例子,因为我没有看到这样做会带来任何性能上的提升。但是,我确实看到查询变成了:

代码语言:javascript
复制
SELECT ... FROM User WhERE ID IN(...)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61256372

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档