Mysql 使用多个包含的sequelize计算联接

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', {

我在sequelize中使用mysql的count方法,但是当我有多个嵌套的include时,count属性会使请求返回较少的结果。这个问题和求和法是一样的

我尝试了属性组和复制,但都没有解决问题

我正在使用Sequelize 4.33.4,但我尝试了Sequelize 5,结果仍然是一样的

型号:

// 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) 此外,尽管您的
属性为:[],但仍有许多来自“命题->粉丝->喜欢”的字段。您也可以尝试将所有属性移动到挑战级别(这可能需要您限定字段名)。谢谢!这个答案对我有帮助