【问题标题】:Sequelize how to add in custom sort function?Sequelize如何添加自定义排序功能?
【发布时间】:2020-11-07 17:46:45
【问题描述】:

我有一个带有字符串列“grades”的表,其中包括以下 ['uni', '9','10',11','12']. 我无法将此列更改为 Int。

我有以下排序代码:

Course.findAll({
  order: [
    ['grade', 'ASC']
  ],
...

但按等级排序会给我以下顺序:

['10','11', '12', '9', 'uni' ]

显然我不希望它按照这个顺序。我查看了 Sequelize 文档,他们似乎有一种方法可以提交自定义函数以进行排序,但我没有示例说明它的外观:

// Will order by  otherfunction(`col1`, 12, 'lalala') DESC
[sequelize.fn('otherfunction', sequelize.col('col1'), 12, 'lalala'), 'DESC'],

(https://sequelize.org/master/manual/model-querying-basics.html#ordering-and-grouping)

有人知道这样做的实现吗?

【问题讨论】:

  • "我无法将此列更改为 Int。"为什么?它实际上意味着什么?
  • 在排序函数中尝试将字符串转换为数字
  • @JanStránský 我不能以任何方式修改表格,我必须按原样使用它。
  • @JanStránský 我想知道排序函数是什么样子的,它是一个简单的 sort(a, b) 返回 [-1,0,1] 吗?
  • 我没有续集的经验,抱歉,只是头脑风暴。你能用整数创建另一个列吗?

标签: javascript node.js sequelize.js


【解决方案1】:

文档确实有点含糊,我只能假设otherfunction 表示方言支持的任何其他功能(mssql / mysql 等)及其所需的参数,但尚未测试此假设.

但是,我找到了使用sequelize.literal 的解决方法:

const customOrder = (column, values, direction) => {
  let orderByClause = 'CASE ';

  for (let index = 0; index < values.length; index++) {
    let value = values[index];

    if (typeof value === 'string') value = `'${value}'`;

    orderByClause += `WHEN ${column} = ${value} THEN '${index}' `;
  }

  orderByClause += `ELSE ${column} END`

  return [Sequelize.literal(orderByClause), direction]
};

请注意,索引不会保持为 int,而是被视为字符串,这是因为此列中的其余值都是字符串,并且在超出 CASE WHEN 链时将按此顺序排序。

你会使用它的方式是:

Course.findAll({
  order: [
    customOrder('grade', ['uni', '9','10','11','12'], 'ASC')
  ],
...

此代码采用一组值(按所需顺序排序),并将它们添加到CASE 子句中,为每个值指定其各自的索引,从而确定顺序。 所以给定上面的值,你最终会得到:

  FROM
    ...
  WHERE
    ...
  ORDER BY CASE WHEN grade = 'uni' THEN '0'
                WHEN grade = '9' THEN '1'
                WHEN grade = '10' THEN '2'
                WHEN grade = '11' THEN '3'
                WHEN grade = '12' THEN '4'
                ELSE grade END ASC

作为参考,我使用了 blog postissue ticket

【讨论】:

    【解决方案2】:

    可以使用 Sequalize.literal 设置 orderby 值,请注意值顺序是 DESC,如果要先显示 10 级,请将其放在最右端。

    Course.findAll({
      order: [
        [Sequelize.literal("grade='uni', grade=9, grade=12, grade=11, grade=10")],
      ],
    ...
    

    按值排序参考:https://www.jianshu.com/p/5c23431b4e03

    Sequalize.literal 参考:https://sequelize.org/v5/class/lib/sequelize.js~Sequelize.html#static-method-literal

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-27
      • 1970-01-01
      • 2011-12-28
      • 2018-03-07
      • 1970-01-01
      • 2020-05-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多