Sequelize js如何获取关联模型的平均值(聚合)

Posted

技术标签:

【中文标题】Sequelize js如何获取关联模型的平均值(聚合)【英文标题】:Sequelize js how to get average (aggregate) of associated model 【发布时间】:2020-05-12 16:28:51 【问题描述】:

我正在尝试使用 sequelize 获得模型“用户”的相关模型“评级”的平均评级。

sequelize.sync(logging: false).then(()=>
  return Model.Rating.findAll(
    attributes: [[Sequelize.fn('avg', Sequelize.col('stars')),'rating']]
  )
).then(res => 
  res = res.map(r => r.get())
  console.log(res);
)

直接从“评级”模型尝试时,我得到了正确的响应:

[  rating: '3.5000000000000000'  ]

但是,当尝试通过“用户”的关联来做同样的事情时,我会得到单独的值而不是平均值。

sequelize.sync(logging: false).then(()=>
  return Model.User.findOne(
    where: id: 7,
    include : [
      model: Model.Rating, as: 'seller_rating',
      attributes: [[Sequelize.fn('avg', Sequelize.col('stars')),'rating']]
    ],
    attributes: 
      exclude: ['password']
    ,
    group: ['seller_rating.id', 'user.id'],
  )
).then(res => 
  res = res.get()
  res.seller_rating = res.seller_rating.map(r => r.get())
  console.log(res)
)

我必须在组中添加“seller_rating.id”和“user.id”,否则 sequelize 会抛出错误。


  id: 7,
  email: 'example@gmail.com',
  createdAt: 2020-01-20T09:07:47.101Z,
  updatedAt: 2020-01-21T08:58:52.036Z,
  seller_rating: [
     rating: '4.0000000000000000' ,
     rating: '3.0000000000000000' 
  ]

以下是用户和评分模型 用户:

let User = sequelize.define('user', 
    email: type: Sequelize.STRING, unique: true, allowNull: false,
    password : type: Sequelize.STRING, ,
)

评分:

let Rating = sequelize.define('rating', 
    seller_id: 
        type: Sequelize.INTEGER,
        references: model: User, key: 'id',
        unique: 'rateObject'
    ,
    buyer_id: 
        type: Sequelize.INTEGER,
        references: model: User, key: 'id',
        unique: 'rateObject'
    ,
    stars: 
        type: Sequelize.INTEGER,
        validate: 
            min: 1,
            max: 5
        ,
        allowNull: false
    
)

Rating.belongsTo(User, onDelete: 'cascade', foreignKey: 'seller_id')
Rating.belongsTo(User, onDelete: 'cascade', foreignKey: 'buyer_id')
User.hasMany(Rating,  foreignKey: 'seller_id', as: 'seller_rating')
User.hasMany(Rating,  foreignKey: 'buyer_id', as: 'buyer_rating')

【问题讨论】:

【参考方案1】:

这个解决方案应该适合你:

Model.User.findOne(
  where:  id: 7 ,
  attributes: [
    [Sequelize.fn('AVG', Sequelize.col('seller_rating.stars')), 'avgRating'],
  ],
  include: [
    
      model: Model.Rating,
      as: 'seller_rating',
      attributes: [],
    ,
  ],
  raw: true,
  group: ['User.id'],
).then((res) => console.log(res));

【讨论】:

有没有办法用聚合来做到这一点?

以上是关于Sequelize js如何获取关联模型的平均值(聚合)的主要内容,如果未能解决你的问题,请参考以下文章

如何通过节点js中的sequelize更新关联记录?

如何使用 sequelize 建立模型属于多关联

在 sequelize.js 中获取与 belongsToMany 的关联

如何在关联表Sequelize js中获取自定义字段

Node.js / Sequelize.js / Express.js - 如何插入多对多关联? (同步/异步?)

Sequelize - 在验证模型的关联时获取正确的路径