Frank Jensen
Frank Jensen

Reputation: 367

Sequelize limit include association

I have a problem with Sequelize when limiting results and including associated models.

The following produces the correct result, limited by 10 and sorted correctly.

Visit.findAll({
  limit: 10,
  order: 'updatedAt DESC',
}).success(function(visits) {
  res.jsonp(visits);
}).failure(function(err) {
  res.jsonp(err);
})

SQL

SELECT * FROM `Visits` ORDER BY updatedAt DESC LIMIT 10;

However when I add an association it suddently limits on the subquery instead and thus the ordering never happens because of a limited result set.

Visit.findAll({
  limit: 10,
  order: 'updatedAt DESC',
  include: [
    { model: Account, required: true }
  ]
}).success(function(visits) {
  res.jsonp(visits);
}).failure(function(err) {
  res.jsonp(err);
})

SQL

SELECT 
  `Visits`.* 
FROM 
  (SELECT 
    `Visits`.*, `Account`.`id` AS `Account.id`, `Account`.`email` AS `Account.email`, `Account`.`password` AS `Account.password`, `Account`.`role` AS `Account.role`, `Account`.`active` AS `Account.active`, `Account`.`createdAt` AS `Account.createdAt`, `Account`.`updatedAt` AS `Account.updatedAt`, `Account`.`practice_id` AS `Account.practice_id` 
  FROM 
    `Visits` INNER JOIN `Accounts` AS `Account` ON `Account`.`id` = `visits`.`account_id` LIMIT 10) AS `visits` 
ORDER BY updatedAt DESC;

What I'm was expecting was having the limit on the top query as so:

SELECT 
  ...
FROM 
  (SELECT ...) AS `Visits`
ORDER BY `Visits`.updatedAt DESC LIMIT 10
LIMIT 10;

Upvotes: 10

Views: 7351

Answers (2)

thanh1101681
thanh1101681

Reputation: 302

  • order field key model order: ['FieldOrder', 'DESC']

ex:

 db.ModelA.findAll({
    include: [{
        model: db.ModelB
    }],
    order: ['CreatedDateModelA', 'DESC']
})
.then(function(response){
}, function(err){
})
  • order field include model order: [ModelInclude,'FieldOrder', 'DESC']

ex:

db.ModelA.findAll({
    include: [{
        model: db.ModelB
    }],
    order: [db.ModelB,'CreatedDateModelA', 'DESC']
})
.then(function(response){

}, function(err){

})

Upvotes: 0

srlm
srlm

Reputation: 3226

You shouldn't use both the key and the direction in a single string on your order. From the docs:

'username DESC', // will return username DESC -- i.e. don't do it!

The correct solution is:

order: ['updatedAt', 'DESC']

Complete working example:

'use strict';

var Sequelize = require('sequelize');
var sequelize = new Sequelize(
    'test', // database
    'test', // username
    'test', // password
    {
        host: 'localhost',
        dialect: 'postgres'
    }
);

var Customer = sequelize.define('Customer', {
    firstName: {type: Sequelize.STRING},
    lastName: {type: Sequelize.STRING}
});

var Order = sequelize.define('Order', {
    amount: {type: Sequelize.FLOAT}
});

var firstCustomer;

Customer.hasMany(Order, {constraints: true});
Order.belongsTo(Customer, {constraints: true});

sequelize.sync({force: true})
    .then(function () {
        return Customer.create({firstName: 'Test', lastName: 'Testerson'});
    })
    .then(function (author1) {
        firstCustomer = author1;
        return Order.create({CustomerId: firstCustomer.id, amount: 10});
    })
    .then(function () {
        return Order.create({CustomerId: firstCustomer.id, amount: 20})
    })
    .then(function () {
        return Order.findAll({
            limit: 10,
            include: [Customer],
            order: [
                ['updatedAt', 'DESC']
            ]
        });
    })
    .then(function displayResults(results) {
        results.forEach(function (c) {
            console.dir(c.toJSON());
        });
    })
    .then(function () {
        process.exit(0);
    });

Produces:

SELECT "Order"."id", "Order"."amount", "Order"."createdAt", "Order"."updatedAt", "Order"."CustomerId", "Customer"."id" AS "Customer.id", "Customer"."firstName" AS "Customer.firstName", "Customer"."lastName" AS "Customer.lastName", "Customer"."createdAt" AS "Customer.createdAt", "Customer"."updatedAt" AS "Customer.updatedAt" FROM "Orders" AS "Order" LEFT OUTER JOIN "Customers" AS "Customer" ON "Order"."CustomerId" = "Customer"."id" ORDER BY "Order"."updatedAt" DESC LIMIT 10;

Upvotes: 5

Related Questions