Mysql 使用多个包含的sequelize计算联接
我在sequelize中使用mysql的count方法,但是当我有多个嵌套的include时,count属性会使请求返回较少的结果。这个问题和求和法是一样的 我尝试了属性组和复制,但都没有解决问题 我正在使用Sequelize 4.33.4,但我尝试了Sequelize 5,结果仍然是一样的 型号:Mysql 使用多个包含的sequelize计算联接,mysql,node.js,sequelize.js,Mysql,Node.js,Sequelize.js,我在sequelize中使用mysql的count方法,但是当我有多个嵌套的include时,count属性会使请求返回较少的结果。这个问题和求和法是一样的 我尝试了属性组和复制,但都没有解决问题 我正在使用Sequelize 4.33.4,但我尝试了Sequelize 5,结果仍然是一样的 型号: // User module.exports = function(sequelize, DataTypes) { var User = sequelize.define('User', {
// User
module.exports = function(sequelize, DataTypes) {
var User = sequelize.define('User', {
userId: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
autoIncrement: true
},
// ...
}, {
tableName: 'user'
});
User.associate = function (models) {
models.User.hasMany(models.Proposition, {foreignKey: 'userId'});
models.User.belongsToMany(models.Proposition, {as: 'Fan', through: 'like', foreignKey: 'userId'});
};
return User;
};
// Proposition
module.exports = function(sequelize, DataTypes) {
const Proposition = sequelize.define('Proposition', {
propositionId: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
autoIncrement: true
},
photo: DataTypes.STRING(150),
}, {
tableName: 'proposition'
});
Proposition.associate = function (models) {
models.Proposition.belongsTo(models.Challenge, {foreignKey: 'challengeId'});
models.Proposition.belongsTo(models.User, {foreignKey: 'userId'});
models.Proposition.belongsToMany(models.User, {as: 'Fan', through: 'like', foreignKey: 'propositionId'});
};
return Proposition;
};
// Challenge
module.exports = function(sequelize, DataTypes) {
const Challenge = sequelize.define('Challenge', {
challengeId: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
autoIncrement: true
},
name: DataTypes.STRING(100),
startDate: DataTypes.DATE,
endDate: DataTypes.DATE,
image: DataTypes.STRING(150),
description: DataTypes.STRING(256),
}, {
tableName: 'challenge'
});
Challenge.associate = function (models) {
models.Challenge.hasMany(models.Proposition, {foreignKey: 'challengeId'});
};
return Challenge;
};
控制器:
exports.getCurrentChallenge = function (req, res) {
logger.debug('Start getCurrentChallenge');
models.Challenge.findOne({
where: {
startDate: {
[Op.lte]: new Date()
},
endDate: {
[Op.gte]: new Date()
}
},
include: [{
model: models.Proposition,
include: [{
model: models.User,
attributes: ['userId', 'firstname', 'lastname', 'profilePicture']
}, {
model: models.User,
as: 'Fan',
attributes: []
}],
required: false,
attributes: [
'propositionId',
[models.sequelize.literal("CONCAT('"+ propositionsPicturesPath + "', `Propositions`.`photo`)"), 'photo'],
[models.sequelize.literal('COUNT(`Propositions->Fan->like`.`userId`)'), 'likes'], // Show less results
[models.sequelize.literal('IFNULL(SUM(`Propositions->Fan->like`.`userId` = ' + req.decoded.userId + '), 0)'), 'liked'] // Show less results
],
group: '`Propositions->Fan->like`.`propositionId`',
}]
}).then(function (challenge) {
return res.status(200).send(challenge);
}, function (err) {
logger.debug(err.name, err.message);
return res.sendStatus(500);
});
};
当我有两个属性时,请求只返回第一个命题(命题ID最低的命题)。当我删除它们时,它会将所有结果发送给我。a)您的结果表明嵌套的include应该是外部联接。。。。因此,添加required:false
(如下所示)可能会解决此问题
b) Sequelize可能混淆了从命题到用户的两种关联。您可以尝试向belongsTo添加别名,例如,models.Proposition.belongsTo(models.User,{as:'whatever',foreignKey:'userId'})代码>并在查找中使用别名:
...
include: [{
model: models.Proposition,
include: [{
model: models.User,
as: 'whatever', /**** b) ****/
required: false, /**** a) #1 ****/
attributes: ['userId', 'firstname', 'lastname', 'profilePicture']
}, {
model: models.User,
as: 'Fan',
required: false, /**** b) #2 ****/
attributes: []
}],
required: false, /** this one is for challenge -> proposition **/
...
希望这有助于……使用findOne()
生成什么SQL?Sequelize在生成LIMIT
关键字时存在一些放置缺陷。@KenOn10它生成了一个限制为1:的where子句,但计数在包含的表上,而不是第一个表上,因此即使使用findAll,结果仍然是一样的。生成的SQL有一些奇怪之处。1) 没有GROUP BY语句。。。因此,您的摘要操作不起作用。您可以尝试将组:[]
移动到质询级别,并在查询中指定所有非摘要字段。2) 此外,尽管您的属性为:[],但仍有许多来自“命题->粉丝->喜欢”的字段。您也可以尝试将所有属性移动到挑战级别(这可能需要您限定字段名)。谢谢!这个答案对我有帮助