web-dev-qa-db-ja.com

nodejsでfindAllのソート順を設定します

私は次のように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でも名前でもソートされていません。解決方法を教えてください。

39
PPShein

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内でオブジェクトを受け取ったら、オブジェクトを注文する必要があります。カスタムオーダーに基づいてオブジェクトの配列を注文することに関する次の質問を確認してください。

別の配列の順序に基づいてオブジェクトの配列をソートするにはどうすればよいですか?

89
James111

MySQLを使用している場合、order by FIELD(id, ...)approach を使用できます。

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

遅いことに注意してください。ただし、JSを使用した手動ソートよりも高速である必要があります。

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

sequlize jsを使用して、特定の列に基づいて昇順または降順でデータを並べ替える場合、次のようにordersequlizeメソッドを使用します。

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

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個のクエリを実行しています。

0