私は次のように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でも名前でもソートされていません。解決方法を教えてください。
Sequelizeでは、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()
promise内でオブジェクトを受け取ったら、オブジェクトを注文する必要があります。カスタムオーダーに基づいてオブジェクトの配列を注文することに関する次の質問を確認してください。
MySQLを使用している場合、order by FIELD(id, ...)
approach を使用できます。
Company.findAll({
where: {id : {$in : companyIds}},
order: sequelize.literal("FIELD(company.id,"+companyIds.join(',')+")")
})
遅いことに注意してください。ただし、JSを使用した手動ソートよりも高速である必要があります。
次のコードを使用すると、非常に手間がかからずにこれを実現できます。
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', [...])
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')
Sequelizeのorder句 でこれが可能だとは思わない。なぜなら、私が知る限り、これらの句はリスト内のすべての要素に適用可能なバイナリ演算であるからだ。 (これは一般にリストのソートがどのように機能するかであるため、これも理にかなっています。)
したがって、order句は、「これらの2つの要素のどちらが古いですか?」一方、順序付けは二項演算(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個のクエリを実行しています。