sequelize findAll Sortierreihenfolge in nodejs

73

Ich versuche, alle Objektlisten aus der Datenbank mit folgendem Sequelize auszugeben, und möchte, dass die Daten sortiert werden, wenn ich die ID in der where-Klausel hinzufüge.

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']
    });
};

Das Problem ist jedoch, dass nach dem Rendern alle Daten wie folgt sortiert werden.

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

Wie ich herausgefunden habe, ist es weder nach ID noch nach Namen sortiert. Bitte helfen Sie mir, wie ich es lösen kann.

PPShein
quelle

Antworten:

171

In der Folge können Sie einfach die Reihenfolge nach Klauseln hinzufügen.

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']
    });
};

Sehen Sie, wie ich das orderArray von Objekten hinzugefügt habe ?

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

Bearbeiten:

Möglicherweise müssen Sie die Objekte bestellen, sobald sie innerhalb des .then()Versprechens eingegangen sind . Überprüfen Sie diese Frage zum Bestellen eines Arrays von Objekten basierend auf einer benutzerdefinierten Reihenfolge:

Wie sortiere ich ein Array von Objekten basierend auf der Reihenfolge eines anderen Arrays?

James111
quelle
Ich möchte so bestellen bei 46128, 2865, 49569, 1488, 45600, 61991, 1418, 61919, 53326, 61680.
PPShein
Hmmm. Das kannst du nicht (soweit ich weiß)! Sie müssen die Objekte sortieren, sobald Sie sie im Versprechen .then () erhalten haben. Warum müssen Sie sie in diesem speziellen Sortiment bestellen?! Gibt es eine Bestellklausel, die dies möglicherweise für Sie tun könnte? @ppshein
James111
5

Wenn Sie Daten sortieren entweder in aufsteigender oder absteigender Reihenfolge basierend auf bestimmten Spalte möchten, verwenden sequlize js, verwenden Sie die orderMethode sequlizewie folgt

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

Mit dem folgenden Code können Sie dies auf sehr rückständige Weise erreichen:

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')
    });
};

Dies ist etwas eingeschränkt, da es nach ein paar Dutzend Datensätzen sehr schlechte Leistungseigenschaften aufweist, aber bei der von Ihnen verwendeten Skala akzeptabel ist.

Dadurch wird eine SQL-Abfrage erstellt, die ungefähr so ​​aussieht:

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

Wenn Sie MySQL verwenden , können Sie folgenden order by FIELD(id, ...) Ansatz verwenden :

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

Denken Sie daran, es könnte langsam sein. Sollte aber schneller sein als manuelles Sortieren mit JS.

Pavlo Razumovskyi
quelle
-1

Ich denke nicht, dass dies in der Ordnungsklausel von Sequelize möglich ist , da diese Klauseln, soweit ich das beurteilen kann, als binäre Operationen gedacht sind, die für jedes Element in Ihrer Liste gelten. (Dies ist auch sinnvoll, da das Sortieren einer Liste im Allgemeinen so funktioniert.)

Eine order-Klausel kann also so etwas wie eine Order bestellen, indem sie darüber rekursiert und fragt: "Welches dieser beiden Elemente ist älter?" Während Ihre Bestellung nicht auf eine binäre Operation ( compare_bigger(1,2) => 2) reduziert werden kann, sondern nur eine beliebige Sequenz ( 2,4,11,2,9,0) ist.

Als ich dieses Problem mit traf findAll, war hier meine Lösung (siehe in Ihren zurückgegebenen Ergebnissen für 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 })});

Welches kehrt zurück [2, 23, 20, 53, 9]. Ich glaube nicht, dass wir einen besseren Kompromiss eingehen können. Sie könnten an Ort und Stelle über Ihre bestellten IDs mit iterieren findOne, aber dann führen Sie n Abfragen durch, wann 1 dies tun wird.

Alex Moore-Niemi
quelle