在 Objection.js 中按急切结果计数排序记录并实现分页?

Posted

技术标签:

【中文标题】在 Objection.js 中按急切结果计数排序记录并实现分页?【英文标题】:Order records by eager results count and implement pagination based on that in Objection.js? 【发布时间】:2019-10-11 01:32:48 【问题描述】:

我有这些表:

    Users Skills Has_skills (user_id, skill_id)

我将一组技能 ID 传递给函数,该函数应该获取至少具有其中一项技能的用户。查询在某种程度上应该是有效的,因此它获取多个用户(限制、范围或换句话说分页功能),但不执行从 ID 0 的用户开始然后向上的范围,而是从用户开始的范围最匹配的技能最少。

那么查询如何按匹配技能的数量从最匹配技能到最少对记录进行排序,以便我可以根据这些结果添加分页?我想我应该另外调整 has_skills 上的 modifyEager 并计算它,然后实现分页范围,但我不完全确定如何做到这一点。所以最终,这就是我需要添加的内容:

    查询应首先按匹配技能的数量对记录进行排序/排序 出于分页目的和更好的性能,上述条件应受用户数量或范围的限制

这是我的功能:

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】:

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

【讨论】:

以上是关于在 Objection.js 中按急切结果计数排序记录并实现分页?的主要内容,如果未能解决你的问题,请参考以下文章

在 SQLite 中按计数排序单行数组

如何在熊猫中按值计数对列进行排序

在一个查询中按计数和运算符获取结果

在一个表1中按月计数(Unix时间戳)并将结果写入表2

在删除表格时在 Objection.js 中保留关系图

在Objection.js中,设置RelationMappings有什么好处?