在Sequelize中填充没有关联ID的数据

时间:2019-03-20 03:42:01

标签: mysql join sequelize.js associations

我有4个表,用户,个人资料,专业,用户专长。我正在使用续集。我的用户模型是->

const User = sequelize.define('user', {
user_id: {
        type: Sequelize.INTEGER,
        allowNull: false,
        primaryKey: true,
        autoIncrement: true,
    },
    IsDeleted: {
        type:Sequelize.BOOLEAN,
    },
    status: {
        type:Sequelize.BOOLEAN,
},
});

我的个人资料模型->

const Profile= sequelize.define('profile', {
    profile_id: {
        type: Sequelize.INTEGER,
        allowNull: false,
        primaryKey: true,
        autoIncrement: true,
    },
    first_name: {
        type:Sequelize.STRING,
    },
    last_name: {
        type:Sequelize.STRING,
    },
},
{
    indexes: [
        {
            unique: true,
            fields: ['user_id']
        }
    ]
});   
Chef_Info.belongsTo(User, {foreignKey: 'user_id'});

特色表->

    const Profile= sequelize.define('speciality', {
        speciality_id: {
            type: Sequelize.INTEGER,
            allowNull: false,
            primaryKey: true,
            autoIncrement: true,
        },
        title: {
            type:Sequelize.STRING,
        },
}

user_specialities拥有用户和专业之间的多对多关系。我已经使用过belongsToMany这样的关联-

Speciality.belongsToMany(User, {through: 'user_speciality',foreignKey: 'speciality_id', otherKey: 'user_id'});
User.belongsToMany(Speciality, {through: 'user_speciality',foreignKey: 'user_id', otherKey: 'speciality_id'});

现在,我想获取具有user_id,first_name,last_name和特殊性的数据。例如->

first_name  | last_name     | specialities
Khabib      | Nurmagamedov  | Athlete, Wrestler
Tony        | Ferguson      | Athlete, Striker

我在MySql中尝试过,查询应该在这里->

SELECT profiles.first_name,profiles.last_name,GROUP_CONCAT(specialities.title)
FROM (
users
    LEFT JOIN profiles
         ON users.user_id = profiles.user_id 
    LEFT JOIN user_specialities
        ON users.user_id = user_specialities.user_id
    LEFT JOIN specialities
        ON chef_specialities.speciality_id = specialities.speciality_id
)
WHERE(
    AND users.IsDeleted = false
    And users.status = true
)
GROUP BY users.user_id;

但是我正在努力将其转换为续集。我走了这么远->

UserSpecialities.findAll({
    attributes:[sequelize.fn('GROUP_CONCAT', sequelize.col('title')), 'speciality_id'],
    include: [
    { 
       model: User,
       attributes: [],
       where:{
           IsRemoved: false,
           status: true,
       },
    },
    { model: Speciality,
         attributes: [],
    },
    ],
    group:['user_id']

它按用户提供专业->

[
    {
        "speciality_id": "Athlete, Wrestler",
    },
    {
        "speciality_id": "Athlete, Striker",
    }
]

但是我无法在此处填充配置文件数据。如果我尝试包含配置文件,它不会显示关联错误,或者尝试在用户模型中添加hasMany会再次引发错误。在这种情况下我该怎么办? 提前谢谢。

1 个答案:

答案 0 :(得分:1)

因为配置文件与用户相关联,但与UserSpecialties没有关联,所以通过两个查询来完成此配置更为有意义。

像上面一样,获取您的用户专业知识,然后获取那些userId并获取其关联的配置文件(应为User.getProfile之类的东西,具体取决于您的关联设置方式)。

现在,您已经将UserSpecialties属性设置为仅返回speciality_id和title,如果将userId添加到这些属性中,则可以使用那些userId来查询您的个人资料表。然后,promise对于这样的事情很有效,例如:

UserSpecialties.findAll({...}).then((userSpecialties) => {
  User.getProfile({where: {userId: userSpecialties.userId}, attributes: {'first_name', 'last_name'})
});

取决于您要具体处理的信息,您可能需要对其进行一些调整,但是一般的想法是将userId添加为属性,然后使用UserSpecialties中的userId在User表中查询配置文件查询结果应该可以很好地处理所需的数据。

尽管查看模型,但仅将profile和user放在一个表中可能是有意义的,其中User具有first_name,last_name,userId和status。由于Profile没有太多其他内容,因此,如果您需要userProfile的特定内容,则可以在用户模型上使用范围。