web-dev-qa-db-fra.com

sequete findAll ordre de tri dans nodejs

J'essaie de sortir toutes les listes d'objets de la base de données avec Sequelize comme suit et je veux obtenir les données qui sont triées à mesure que j'ajoute id dans la clause where.

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

Mais le problème est qu'après le rendu, toutes les données sont triées comme suit.

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

Comme je l'ai trouvé, ce n'est ni trié par id ni nom. S'il vous plaît aidez-moi comment le résoudre.

22
PPShein

En sequelize, vous pouvez facilement ajouter des clauses d'ordre par.

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

Vous voyez comment j'ai ajouté le tableau order

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

Modifier:

Vous devrez peut-être commander les objets une fois qu'ils auront été reçus dans la promesse .then(). Consultez cette question sur la commande d'un tableau d'objets basé sur un ordre personnalisé:

Comment trier un tableau d'objets en fonction de l'ordre d'un autre tableau?

49
James111

Si vous utilisez MySQL, vous pouvez utiliser order by FIELD(id, ...)approche :

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

Gardez à l'esprit, cela pourrait être lent. Mais cela devrait être plus rapide que le tri manuel avec JS.

1
Pavlo Razumovskyi

Vous pouvez accomplir cela de manière très arriérée avec le code suivant:

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

Ceci est quelque peu limité car il présente de très mauvaises performances après quelques dizaines d'enregistrements, mais il est acceptable à l'échelle utilisée.

Cela produira une requête SQL qui ressemble à ceci:

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

Si vous souhaitez trier les données en ordre croissant ou décroissant en fonction d'une colonne particulière, utilisez sequlize js, utilisez la méthode order de sequlize comme suit

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

Je ne pense pas que cela soit possible dans la clause d'ordre de Sequelize , car, autant que je sache, ces clauses sont censées être des opérations binaires applicables à tous les éléments de votre liste. (Cela a également un sens, car c’est généralement le mode de tri d’une liste.)

Ainsi, une clause de commande peut faire quelque chose de similaire à la commande de la liste en demandant à chaque élément "lequel de ces 2 éléments est le plus ancien?" Alors que votre ordre n’est pas réductible à une opération binaire (compare_bigger(1,2) => 2), il s’agit simplement d’une séquence arbitraire (2,4,11,2,9,0).

Lorsque j'ai trouvé ce problème avec findAll, voici ma solution (dans vos résultats renvoyés pour 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 })});

Ce qui retourne [2, 23, 20, 53, 9]. Je ne pense pas que nous puissions faire un meilleur compromis. Vous pouvez effectuer une itération sur vos ID commandés avec findOne, mais vous effectuez ensuite n requêtes quand 1 le fera.

0
Alex Moore-Niemi