How to configure sequelize to return embedded array in a one-to-many association?

Aja*_*jar 7 node.js express sequelize.js

here is the deal:

I have two models - User and House
User has many houses
House belongs to a User

I've entered some dummy data and created a minimal express app to serve an api
I want to return a list of users and include each users houses.

api 端点如下所示:

router.get('/users', function(req, res,next) {
  models.User.findAll({
      include: [ models.House ],
      raw: true // returns result-set as a clean json...
  })
  .then(function(users) {
      d('num users found: ' + users.length);
      res.json(users);
  })
  .catch(function(err){
      d('DB ERROR: '+err.message);
      next(err);
  });

});
Run Code Online (Sandbox Code Playgroud)

Sequelize 的默认行为是返回相同用户数据的多个实例,每次都有不同的房屋数据,如下所示:

[
  {
    id: 1,
    first_name: "aa",
    last_name: "aaaaaa",
    email: "aa@aa.aa",
    Houses.id: 1,
    Houses.description: "house 1 desc",
    Houses.user_id: 1
  },
  {
    id: 1,
    first_name: "aa",
    last_name: "aaaaaa",
    email: "aa@aa.aa",
    Houses.id: 3,
    Houses.description: "house 3 desc",
    Houses.user_id: 1
  },
  {
    id: 2,
    first_name: "bb",
    last_name: "bbbbbb",
    email: "bb@bb.bb",
    Houses.id: 2,
    Houses.description: "house 2",
    Houses.user_id: 2
  }
]
Run Code Online (Sandbox Code Playgroud)

我可以在拥有用户中嵌入一系列房屋吗?
有没有办法配置 Sequelize 来返回这样的数据:

[
  {
    id: 1,
    first_name: "aa",
    last_name: "aaaaaa",
    email: "aa@aa.aa",
    Houses:[
       {
          id: 1,
          description: "house 1 desc",
          user_id: 1
       },
       {
          id: 3,
          description: "house 3 desc",
          user_id: 1
       },
    ]
  },

  {
    id: 2,
    first_name: "bb",
    last_name: "bbbbbb",
    email: "bb@bb.bb",
    Houses:[
       {
          id: 2,
          description: "house 2",
          user_id: 2
       }
    ]
  }
]
Run Code Online (Sandbox Code Playgroud)

如果答案是否定的,您能否推荐一种将数据解析为这种结构的方法?

用户模型:

module.exports = function(sequelize, DataTypes) {

  var User = sequelize.define('User', {

        first_name: DataTypes.STRING,
        last_name: DataTypes.STRING,
        email: DataTypes.STRING

    }, 
    {
      classMethods: {
        associate: function(models) {
          User.hasMany(models.House)
        }
      }
  });

  return User;
};
Run Code Online (Sandbox Code Playgroud)

房屋模型:

module.exports = function(sequelize, DataTypes) {
  var House = sequelize.define("House", {
      description: DataTypes.TEXT
  }, 
  {
    classMethods: {
      associate: function(models) {
        House.belongsTo(models.User);
      }
    }
  });

  return House;
};
Run Code Online (Sandbox Code Playgroud)

Cor*_*ies 7

我遇到了类似的问题,刚刚找到了一个似乎适用于我的情况的解决方案:

router.get('/users', function(req, res, next) {
  models.User.findAll({
      include: [ {model: models.House, as: 'houses'} ],
      raw: false // returns result-set as sequelize object...
  })
  .then(function(users) {
      users = users.get(); //turns sequelize object into json
      d('num users found: ' + users.length);
      res.json(users);
  })
  .catch(function(err){
      d('DB ERROR: '+err.message);
      next(err);
  });

});
Run Code Online (Sandbox Code Playgroud)

将 raw 设置为 false(或让它默认为),然后,任何时候你需要在 res.json 之前获取原始 json,使用users.get()(“users”现在是一个 sequelize 实例),你可以得到那个 sequelize 对象的 json那现在是一个带有关联数组的对象!

  • 似乎将 raw: false 而不是 raw:true 解决了问题,但我没想到 raw 选项会出现这种行为。据我了解,该选项应该只返回来自数据库的纯响应,而不是使用所有元数据信息续集对象。 (2认同)

Ale*_*isi 0

尝试将 'as' 选项添加到 User->House 1:n 关系中

module.exports = function(sequelize, DataTypes) {

      var User = sequelize.define('User', {

            first_name: DataTypes.STRING,
            last_name: DataTypes.STRING,
            email: DataTypes.STRING

        }, 
        {
          classMethods: {
            associate: function(models) {
              User.hasMany(models.House, {as: 'houses'})
            }
          }
      });

      return User;
    };
Run Code Online (Sandbox Code Playgroud)

并相应地更新查询

router.get('/users', function(req, res,next) {
  models.User.findAll({
      include: [ {model: models.House, as: 'houses'} ],
      raw: true // returns result-set as a clean json...
  })
  .then(function(users) {
      d('num users found: ' + users.length);
      res.json(users);
  })
  .catch(function(err){
      d('DB ERROR: '+err.message);
      next(err);
  });

});
Run Code Online (Sandbox Code Playgroud)