简体   繁体   English

如何在Sequelize中查询多对多关系数据

[英]How to query many-to-many relationship data in Sequelize

I have got a many-to-many relationship between two models, users and groups. 我在两个模型(用户和组)之间建立了多对多关系。

I have two models which are specifying the belongsToMany with a foreignKey and through attribute. 我有两个模型,它们用一个foreignKey和through属性指定belongsToMany。

Users model 用户模型

'use strict';
module.exports = function(sequelize, DataTypes) {
  var User = sequelize.define('User', {
    firstName: DataTypes.STRING,
    lastName: DataTypes.STRING,
    email: DataTypes.STRING,
    username: DataTypes.STRING,
    facebookId: DataTypes.STRING,
    password: DataTypes.STRING,
  }, {
    classMethods: {
      associate: function(models) {
        User.hasMany(models.Payment);
        User.hasMany(models.Friend, {foreignKey: 'userIdLink1'});
        User.belongsToMany(models.Group, { through: 'UsersGroups', foreignKey: 'facebookId' });
      }
    },
    instanceMethods: {
      toJSON: function () {
        var values = Object.assign({}, this.get());

        delete values.password;
        return values;
      }
    }
  });
  return User;
};

groups model 组模型

'use strict';
module.exports = function(sequelize, DataTypes) {
  var Group = sequelize.define('Group', {
    name: DataTypes.STRING
  }, {
    classMethods: {
      associate: function(models) {
        // associations can be defined here
        Group.belongsToMany(models.User, {through: 'UsersGroups', foreignKey: 'groupId'});
        Group.hasMany(models.Payment)
      }
    },
    instanceMethods: {
      toJSON: function () {
        var values = Object.assign({}, this.get());

        delete values.password;
        return values;
      }
    }
  });
  return Group;
};

which are being joined via a junction table UsersGroups 通过联结表UsersGroups加入的

This works fine and I can create a new group and it links the user with it successfully but when I try fetch the data the SQL query is trying to find Groups based on User.id as opposed to User.facebookId like I specified in my model User.belongsToMany(models.Group, { through: 'UsersGroups', foreignKey: 'facebookId' }); 这可以正常工作,我可以创建一个新组,并且可以成功地将用户与其链接,但是当我尝试获取数据时,SQL查询将尝试基于User.id而不是像我在模型中指定的User.facebookId来查找组User.belongsToMany(models.Group, { through: 'UsersGroups', foreignKey: 'facebookId' });

I call the following code to fetch the data: 我调用以下代码来获取数据:

const options = {
        where: {
                    facebookId: facebookId, 

      },
      defaults: {
            firstName: data.firstName,
            lastName: data.lastName,
            email: data.email,
            facebookId: facebookId
        },
        include: [
            { model: db.Group }
        ]
    }

    db.User.findOrCreate(options)
        .then((user) => {
            res.send(user)
        }, (err) => {
            res.status(500).send(err)
        })

and it returns a user but with an empty Groups array which is incorrect as there is definitely data there as I can create it fine and see it in the DB. 它返回一个用户,但有一个空的Groups数组,这是不正确的,因为那里肯定有数据,因为我可以很好地创建它并在数据库中查看它。

You can see the SQL query that is generated by Sequelize here: 您可以在此处查看由Sequelize生成的SQL查询:

SELECT `User`.*, `Groups`.`id` AS `Groups.id`, `Groups`.`name` AS `Groups.name`, `Groups`.`createdAt` AS `Groups.createdAt`, `Groups`.`updatedAt` AS `Groups.updatedAt`, `Groups.UsersGroups`.`createdAt` AS `Groups.UsersGroups.createdAt`, `Groups.UsersGroups`.`updatedAt` AS `Groups.UsersGroups.updatedAt`, `Groups.UsersGroups`.`facebookId` AS `Groups.UsersGroups.facebookId`, `Groups.UsersGroups`.`groupId` AS `Groups.UsersGroups.groupId` 
FROM (
    SELECT `User`.`id`, `User`.`firstName`, `User`.`lastName`, `User`.`email`, `User`.`username`, `User`.`facebookId`, `User`.`password`, `User`.`createdAt`, `User`.`updatedAt` FROM `Users` AS `User`     WHERE `User`.`facebookId` = '1341052992643877' LIMIT 1) AS `User` 
    LEFT OUTER JOIN (`UsersGroups` AS `Groups.UsersGroups` 
    INNER JOIN `Groups` AS `Groups` ON `Groups`.`id` = `Groups.UsersGroups`.`groupId`
    ) 
ON `User`.`id` = `Groups.UsersGroups`.`facebookId`;

Note the last line 注意最后一行

ON `User`.`id` = `Groups.UsersGroups`.`facebookId`

needs to be 需要是

ON `User`.`facebookId` = `Groups.UsersGroups`.`facebookId`

Turns out I had to specify facebookId as a primary key in my user model 原来我必须在用户模型中将facebookId指定为主键

    facebookId: {
      type: DataTypes.STRING,
      primaryKey: true,
    },

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM