sequelize在nodejs中查找所有排序顺序

时间:2016-03-28 09:33:01

标签: node.js express sequelize.js

我正在尝试使用sequelize从数据库输出所有对象列表,如下所示,并希望获取数据,因为我在where子句中添加了id。

exports.getStaticCompanies = function () {
    return Company.findAll({
        where: {
            id: [46128, 2865, 49569,  1488,   45600,   61991,  1418,  61919,   53326,   61680]
        },
        attributes: ['id', 'logo_version', 'logo_content_type', 'name', 'updated_at']
    });
};

但问题是在渲染之后,所有数据都按照以下方式排序。

46128, 53326, 2865, 1488, 45600, 61680, 49569, 1418, ....

正如我发现的那样,它既没有按ID也没有按名称排序。请帮我解决一下。

6 个答案:

答案 0 :(得分:63)

在续集中,您可以轻松地按子句添加顺序。

exports.getStaticCompanies = function () {
    return Company.findAll({
        where: {
            id: [46128, 2865, 49569,  1488,   45600,   61991,  1418,  61919,   53326,   61680]
        }, 
        // Add order conditions here....
        order: [
            ['id', 'DESC'],
            ['name', 'ASC'],
        ],
        attributes: ['id', 'logo_version', 'logo_content_type', 'name', 'updated_at']
    });
};

了解我是如何添加order对象数组的?

order: [
      ['COLUMN_NAME_EXAMPLE', 'ASC'], // Sorts by COLUMN_NAME_EXAMPLE in ascending order
],

编辑:

您可能需要在.then()承诺内收到对象后对其进行排序。查看关于根据自定义顺序排序对象数组的问题:

How do I sort an array of objects based on the ordering of another array?

答案 1 :(得分:1)

您可以使用以下代码以非常反手的方式完成此任务:

exports.getStaticCompanies = function () {
    var ids = [46128, 2865, 49569, 1488, 45600, 61991, 1418, 61919, 53326, 61680]
    return Company.findAll({
        where: {
            id: ids
        },
        attributes: ['id', 'logo_version', 'logo_content_type', 'name', 'updated_at'],
        order: sequelize.literal('(' + ids.map(function(id) {
            return '"Company"."id" = \'' + id + '\'');
        }).join(', ') + ') DESC')
    });
};

这有点受限,因为它在几十条记录之后的性能特征非常糟糕,但它在您使用的规模上是可以接受的。

这将产生一个如下所示的SQL查询:

[...] ORDER BY ("Company"."id"='46128', "Company"."id"='2865', "Company"."id"='49569', [...])

答案 2 :(得分:1)

如果您使用 MySQL ,则可以使用order by FIELD(id, ...) approach

Company.findAll({
    where: {id : {$in : companyIds}},
    order: sequelize.literal("FIELD(company.id,"+companyIds.join(',')+")")
})

请记住,它可能会很慢。但是应该比用JS手动排序更快。

答案 3 :(得分:0)

我认为这不可能在Sequelize's order clause中,因为据我所知,这些子句是适用于列表中每个元素的二元操作。 (这也是有道理的,因为它通常是如何对列表进行排序的。)

所以,一个order子句可以做一些事情,就像通过递归来命令一个列表,询问“这两个元素中哪一个更旧?”虽然您的排序不能简化为二进制操作(compare_bigger(1,2) => 2),但只是一个任意序列(2,4,11,2,9,0)。

当我使用findAll点击此问题时,这是我的解决方案(在numbers的返回结果中的子字段):

var numbers = [2, 20, 23, 9, 53];
var orderIWant = [2, 23, 20, 53, 9];
orderIWant.map(x => { return numbers.find(y => { return y === x })});

返回[2, 23, 20, 53, 9]。我不认为我们可以做出更好的权衡。您可以使用findOne在已排序的ID上进行迭代,但是当1执行时,您将进行n次查询。

答案 4 :(得分:0)

如果您要使用sequlize js根据特定列以升序或降序对数据进行排序,请按如下方式使用order的{​​{1}}方法

sequlize

答案 5 :(得分:0)

可能有点晚了,但想提一个方法。
基于[46128, 2865, 49569, 1488, 45600, 61991, 1418, 61919, 53326, 61680] 的排序可以使用 SQL 的 ARRAY_POSITION 函数来完成。 >

const arr = [46128, 2865, 49569,  1488,   45600,   61991,  1418,  61919,   53326,   61680];
const ord = [sequelize.literal(`ARRAY_POSITION(ARRAY[${arr}]::integer[], "id")`)];

return Company.findAll({
    where: {
        id: arr
    },
    attributes: ['id', 'logo_version', 'logo_content_type', 'name', 'updated_at'],
    order: ord,
});