Как использовать dataloader? - PullRequest
1 голос
/ 16 апреля 2020

Я пытаюсь понять это.

Я хочу получить всех моих пользователей из моей базы данных, кэшировать их, а затем при создании нового запроса я хочу получить те, которые я кэшировал, + новые, которые были созданы.

Пока:

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();
}

метод загрузки требует параметр, но в этом случае я не хочу иметь определенного пользователя c Я хочу их всех.

Я не понимаю, как реализовать это, может кто-то, пожалуйста, объясните.

Ответы [ 2 ]

1 голос
/ 17 апреля 2020

Мне потребовалось время, но я получил эту работу:

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)),
  }),
});

resolver:

  user: {
    myUsers: ({ Id }, args, { userLoader }) => {
      return userLoader.load(Id);
    },
  },

детская площадка:

{users
{Id
myUsers
{Id}}
}

детская игровая площадка объяснена:

пользователи в основном выбирают всех пользователей, а затем myusers делает то же самое, вводя идентификатор из первого вызова.

Я думаю, что я выбрал здесь ужасный пример, так как я не видел никакого выигрыша в этом. Однако я увидел, что запрос превратился в:

SELECT ... FROM User WhERE ID IN(...)
1 голос
/ 16 апреля 2020

Если вы пытаетесь просто загрузить все записи, то нет смысла использовать DataLoader для начала. Цель DataLoader - объединить несколько вызовов, таких как load(7) и load(22), в один вызов. затем выполняется в отношении вашего источника данных. Если вам нужно получить всех пользователей, вам нужно просто вызвать user.findAll напрямую.

Кроме того, если вы в конечном итоге используете DataLoader, убедитесь, что вы передаете функцию, а не объект в качестве контекста. Функция будет выполняться при каждом запросе, что обеспечит использование экземпляра DataLoader fre sh вместо одного со устаревшим кэшем.

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)
  }),
}),

Обратите внимание, что вы также можете вернуть экземпляр ошибка вместо null внутри массива, если вы хотите load отклонить.

...