续集限制包括关联
Posted
技术标签:
【中文标题】续集限制包括关联【英文标题】:Sequelize limit include association 【发布时间】:2015-03-26 07:19:28 【问题描述】:在限制结果和包含关联模型时,我遇到了 Sequelize 问题。
以下产生正确的结果,限制为 10 并正确排序。
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;
但是,当我添加一个关联时,它突然限制了子查询,因此由于结果集有限,排序永远不会发生。
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;
我所期待的是***查询的限制是这样的:
SELECT
...
FROM
(SELECT ...) AS `Visits`
ORDER BY `Visits`.updatedAt DESC LIMIT 10
LIMIT 10;
【问题讨论】:
【参考方案1】:您不应该在订单的单个字符串中同时使用键和方向。来自docs:
'用户名 DESC', // 将返回
username DESC
-- 即不要这样做!
正确的解决方法是:
order: ['updatedAt', 'DESC']
完整的工作示例:
'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);
);
生产:
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;
【讨论】:
我遇到了和上面一样的问题,如果我尝试上面的解决方案,它会在子查询和外部添加一个 order by 子句。在子查询之外失败并出现错误 ofcourse 'unknown column ... in order clause'。 不确定为什么这是公认的答案,即使“订单”确实存在问题。要避免子查询并在末尾保留 LIMIT,您需要调用 findAll( subQuery: false, ...) 或 findAll(include: duplicating: false, ...)。另见***.com/questions/26021965/…【参考方案2】: 订单字段键型号order: ['FieldOrder', 'DESC']
例如:
db.ModelA.findAll(
include: [
model: db.ModelB
],
order: ['CreatedDateModelA', 'DESC']
)
.then(function(response)
, function(err)
)
订单字段包括型号
order: [ModelInclude,'FieldOrder', 'DESC']
例如:
db.ModelA.findAll(
include: [
model: db.ModelB
],
order: [db.ModelB,'CreatedDateModelA', 'DESC']
)
.then(function(response)
, function(err)
)
【讨论】:
以上是关于续集限制包括关联的主要内容,如果未能解决你的问题,请参考以下文章