2016-03-28 1 views
6

Je suis en train de sortie tous liste d'objets de base de données avec sequelize comme suivre et que vous souhaitez obtenir des données sont triées comme je l'ai ajouté id dans la clause where.sequelize ordre de tri findAll dans nodejs

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 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é, il n'est ni trié par identifiant ni nom. S'il vous plaît aidez-moi comment le résoudre.

Répondre

11

En sequelize vous pouvez facilement ajouter des clauses par ordre.

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

Voyez comment j'ai ajouté le tableau order?

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

Edit:

Vous pourriez avoir à commander les objets une fois qu'ils ont été recieved dans la promesse .then(). Checkout cette question sur la commande d'un tableau d'objets en fonction d'un ordre personnalisé:

How do I sort an array of objects based on the ordering of another array?

+0

Je veux commander comme ça par '46128, 2865, 49569, 1488, 45600, 61991, 1418, 61919, 53326, 61680'. – ppshein

+0

Hmmm. Vous ne serez pas capable de faire ça (pour autant que je sache)! Vous devrez regarder dans le tri des objets une fois que vous les avez reçus dans la promesse .then()? Pourquoi avez-vous besoin de les commander dans cette gamme spécifique ?! Y a-t-il une clause d'ordre qui pourrait peut-être le faire pour vous? @ppshein – James111

0

Je ne pense pas que ce soit possible Sequelize's order clause, car pour autant que je peux dire, sont destinés ces clauses à binaire opérations applicables à chaque élément de votre liste. Donc, une clause de commande peut faire quelque chose comme ordonner une liste en récurant sur elle demandant "lequel de ces 2 éléments est le plus ancien?" Alors que votre commande ne se réduit pas à une opération binaire (compare_bigger(1,2) => 2), mais est juste une séquence arbitraire (2,4,11,2,9,0).

Quand je frappe cette question avec findAll, ici était ma solution (sous dans vos résultats retourné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 })}); 

qui retourne [2, 23, 20, 53, 9]. Je ne pense pas qu'il y ait un meilleur compromis que nous pouvons faire. Vous pouvez itérer en place sur vos ids commandés avec findOne, mais vous faites quand n requêtes 1 fera.

1

Vous pouvez accomplir cela dans un très chemin main 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ée, car il possède des caractéristiques très mauvaises performances passées quelques dossiers douzaine, mais il est acceptable à l'échelle tu utilises

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

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

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

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

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