Упорядочить записи по количеству результатов и реализовать нумерацию страниц в Objection.js? - PullRequest
0 голосов
/ 11 октября 2019

У меня есть эти таблицы:

  1. Users
  2. Skills
  3. Has_skills (user_id, skill_id)

ЯПередача массива идентификаторов навыков в функцию, которая должна вызывать пользователей, у которых есть хотя бы один из этих навыков. Запрос должен быть эффективным таким образом, чтобы он выбирал несколько пользователей (ограничение, диапазон или, другими словами, функциональность разбиения на страницы), но не выполнял диапазон, начиная с пользователя с идентификатором 0 и затем вверх, но диапазон начиная с пользователя снаиболее подходящие навыки по меньшей мере.

Итак, как запрос может сортировать записи по количеству совпадающих навыков от наиболее подходящих навыков до минимума, чтобы я мог добавить нумерацию страниц на основе этих результатов? Я предполагаю, что должен дополнительно настроить modifyEager на has_skills и посчитать его, а затем реализовать диапазон разбивки на страницы, но я не совсем уверен, как это сделать. Итак, в конечном итоге, это то, что мне нужно добавить:

  1. Запрос должен сначала выполнить упорядочение / сортировку записей по количеству совпадающих навыков
  2. Вышеуказанное условие должно быть ограниченопо количеству пользователей или диапазон для нумерации страниц и повышения производительности

Это моя функция:

async function getUsersWithPassedSkillIds({ skillIds }) {
    const users = await User.query()
        .select('users.id', 'users.name')
        .joinEager('has_skills')
        .modifyEager('has_skills', builder => builder.select('id', 'name'))
        .whereIn('has_skills.id', skillIds)

    return users
}

1 Ответ

0 голосов
/ 11 октября 2019

Автор Objection.js помог мне сделать эту работу!

// Fetch the users who have at least one matching skill
const hasSkillsSubquery = User.relatedQuery("skills").whereIn(
  "has_skills.skill_id",
  skillIds
);

const users = await User.query()
  .select("users.id", "users.name")
  // Use .eager instead of .joinEager as pagination doesn't work with it due to joins.
  .eager("skills")
  // Optional: Populating the matched skills
  .modifyEager("skills", builder =>
    builder.select("skills.id", "skills.name").whereIn("skills.id", skillIds)
  )
  // Only taking into account users who have at least 1 matched skill
  .whereExists(hasSkillsSubquery.clone())
  // Sorting users by matched skills
  .orderByRaw("(?) DESC", hasSkillsSubquery.clone().count())
  // This would return the user with the most matched skills.
  // If you want to fetch 10 users ordered by number of matching skills: .range(0, 9)
  .range(0, 0);
...