在nodejs中sequelize findAll排序顺序

问题描述 投票:0回答:10

我正在尝试使用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 也不按名称排序。请帮我解决一下。

node.js express sequelize.js
10个回答
320
投票

在续集中,您可以轻松添加 order by 子句。

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()
承诺范围内收到物品后,您可能需要订购这些物品。查看有关根据自定义顺序对对象数组进行排序的问题:

如何根据另一个数组的顺序对对象数组进行排序?


13
投票

如果您想根据特定列以升序或降序对数据进行排序,请使用

sequlize js
,请使用
order
sequlize
方法,如下所示

// Will order the specified column by descending order
order: sequelize.literal('column_name order')
e.g. order: sequelize.literal('timestamp DESC')

8
投票

如果您使用MySQL,您可以使用

order by FIELD(id, ...)
方法

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

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


5
投票

您可以使用以下代码以非常间接的方式完成此操作:

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', [...])

5
投票

可能有点晚了,但想提一下方法。
基于[46128, 2865, 49569, 1488, 45600, 61991, 1418, 61919, 53326, 61680]的排序可以使用postgreSQL的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,
});

0
投票

我认为这在 Sequelize 的 order 子句中是不可能的,因为据我所知,这些子句意味着适用于列表中每个元素的二元运算。 (这也是有道理的,因为这通常是对列表进行排序的工作方式。)

因此,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 个查询。


0
投票
如果需要,数据库会按照字段顺序中值的通用顺序对输出进行排序。

如果您的订单不是这样,您可以在 select 中添加一个 order_field,并根据 id 中的值给它一个值:

case when id=46128 then 0 when id=2865 then 1 when id=49569 then 2 end as order_field and order by order_field.
如果有很多值,您可以将它们按原始顺序填充到具有标识主键 order_field 的临时表中,并通过值字段将您的选择内部连接到该临时表,按 order_field 排序。

我不知道如何在续集中执行此操作,但在这里找到了有关它如何执行我需要的操作的答案。


0
投票
通过在属性名称周围使用

“”引号为我工作。
用于调试 您可以查看由sequelize 生成的查询是什么,然后尝试在特定的数据库控制台上运行它。

就我而言,我无法按最后

updatedAt

 列对数据进行排序
代码片段:

exports.readAll = (req, res) => { console.log("Inside ReadAll Data method"); let data; if (!req.body) { data = CompanyModel.findAll({ order: [[sequelize.literal('"updatedAt"'), 'DESC']]}); } else { data = CompanyModel.findAll({ order: [[sequelize.literal('"updatedAt"'), 'DESC']]}); } data .then((data) => { res.send( data ); }) .catch((err) => { res.status(500).send({ message: err.message || "Some error occurred while retrieving data.", }); }); };
在我的案例中形成 SQL 查询:

Inside ReadAll Data method Executing (default): SELECT "company_name", "company_id", "on_record", "createdAt", "updatedAt" FROM "companies" AS "company" ORDER BY "updatedAt" DESC;
    

0
投票
如果有人使用 uuid 类型,请使用上面 @Agniveer 的示例但已修改

const ids = [ 'f01a057e-5646-4527-a219-336804317246', 'ee900087-4910-42b4-a559-06aea7b4e250', 'b363f116-1fc5-473a-aed7-0ceea9beb14d' ]; const idsFormat = `'${ids.join("','")}'`; const order = [sequelize.literal(`ARRAY_POSITION(ARRAY[${idsFormat}]::uuid[], "<insert_table_name>"."id")`)];
    

0
投票
Model.findAll({ order: [[ 'createdAt' , 'DESC']]});

© www.soinside.com 2019 - 2024. All rights reserved.