我有一个场景,我试图用两个相互关联的表(引用和用户)查询父表(文档),这些表彼此没有关系,但确实与父表有关系。在SQL中,此查询看起来像这样并正确输出我要查找的数据:
select *
from `document`
left join `user`
on `document`.`user_id` = `user`.`user_id`
left join `reference`
on `document`.`reference_id` = `reference`.`reference_id`
where `user`.`organization_id` = 1;
但是,嵌套的关联必须按层次顺序关联才能使查询起作用。由于嵌套关联彼此不相关,因此会出现关联错误。我怎样才能避免这个错误? required: false
会对此产生影响吗?
models.Document.findAll({
order: 'documentDate DESC',
include: [{
model: models.User,
where: { organizationId: req.user.organizationId },
include: [{
model: models.Reference,
}]
}],
})
错误:
未处理拒绝错误:引用与用户无关!
协会:
Document
:
associate: function(db) {
Document.belongsTo(db.User, {foreignKey: 'user_id'}),
Document.belongsTo(db.Reference, { foreignKey: 'reference_id'});;
}
Reference
:
associate: function(db){
Reference.hasMany(db.Document, { foreignKey: 'reference_id' });
}
我应该直接链接查询吗?
答案 0 :(得分:2)
如果要复制查询(尽可能接近),请使用以下查询。请注意,用户where
上的include
仅用于删除Document.user_id
与User.organization_id
不匹配的Document
匹配,但User.organization_id
仍会被退回如果您要省略required: true
不匹配的文档,请使用User <- Document -> Reference
。
models.Document.findAll({
// this is an array of includes, don't nest them
include: [{
model: models.User,
where: { organization_id: req.user.organization_id }, // <-- underscored HERE
required: true, // <-- JOIN to only return Documents where there is a matching User
},
{
model: models.Reference,
required: false, // <-- LEFT JOIN, return rows even if there is no match
}],
order: [['document_date', 'DESC']], // <-- underscored HERE, plus use correct format
});
@echo off
set arg1=%1
shift
javac -cp . %arg1%.java
java %arg1%
pause
答案 1 :(得分:0)
错误表明User
模型未与Reference
模型相关联,但您的描述中只有Document
和Reference
模型的定义。您正在使用include
选项在查询中加入这些表,因此您必须确保它们已关联。您在技术上也不需要此处foreignKey
,您指定的是默认值。
添加Reference->User
关联
associate: function(db) {
// belongsTo()? maybe another relationship depending on your data model
Reference.belongsTo(db.User, {foreignKey: 'user_id'});
Reference.hasMany(db.Document, { foreignKey: 'reference_id' });
}
您也可能在模型定义中设置了underscored: true
,因此您的查询应该反映这一点。此外,如果您要执行LEFT JOIN
,则需要在required: false
上指定include
,否则它是常规JOIN
,并且您只会返回包含匹配项的行include
d模型。您还使用了错误的order
格式,它应该是一个值数组,要按model.document_date DESC
排序,您应该使用order: [['document_date', 'DESC']]
。
正确的查询参数
models.Document.findAll({
order: [['document_date', 'DESC']], // <-- underscored HERE, plus use correct format
include: [{
model: models.User,
where: { organization_id: req.user.organization_id }, // <-- underscored HERE
required: false, // <-- LEFT JOIN
include: [{
model: models.Reference,
required: false, // <-- LEFT JOIN
}]
}],
});
如果您仍然遇到问题,请尝试通过在Sequelize连接中设置logging: console.log
启用日志记录,该连接将显示您在控制台中运行的所有查询。
答案 2 :(得分:0)
在我看来,您的问题可能是关联,尝试链接回文档上的主键而不是列&#39; user_id&#39;和&#39; reference_id&#39;。你没有发布表属性,所以我可能已经理解了这个错误。
文件上的关联是可以的。
associate: function(db) {
Document.belongsTo(db.User, {foreignKey: 'user_id'}), //key in documents
Document.belongsTo(db.Reference, { foreignKey: 'reference_id'}); //key in documents
}
associate: function(db) {
User.belongsTo(db.Document, {
foreignKey: 'id', //Key in User
targetKey: 'user_id' //Key in Documents
}),
}
associate: function(db) {
Reference.belongsTo(db.Document, {
foreignKey: 'id', //Key in reference
targetKey: 'reference_id' //Key in Documents
}),
}
对于debbuging,请考虑使用日志记录,以便查看查询。
var sequelize = new Sequelize('database', 'username', 'password', {
logging: console.log
logging: function (str) {
// do your own logging
}
});