Mongoose/Mongodb Aggregate - 对多个字段进行分组和平均

Posted

技术标签:

【中文标题】Mongoose/Mongodb Aggregate - 对多个字段进行分组和平均【英文标题】:Mongoose/Mongodb Aggregate - group and average multiple fields 【发布时间】:2021-10-22 18:40:35 【问题描述】:

我有一个包含 2 个字段的 Post 模型:日期和评级。我将如何获得每个日期的平均总评分?因此,首先按日期分组,然后在该日期的所有帖子中平均评分。我需要在 mongoose 中执行此操作,但他们的文档很难理解。

const PostSchema = new Schema(
    date: 
      type: String,
      default: getToday() //this is just a new Date() formatted
    ,
    rating: 
      type: Number,
      required: true
    
  , 
) 

这给了我所有日期的平均值,但我不知道如何按日期过滤它:

Post.aggregate([
     $group:  _id: null, avgRating:  $avg: '$rating' 
  ])
  .then(function (res) 
    console.log(res[0]["avgRating"]); 
  )

【问题讨论】:

你需要使用$group$avg累加器,比如$group: "_id" : "$date" , "date_average" : "$avg" : "$rating" 【参考方案1】:

这对我有用:

  Post.aggregate([
     $group:  _id: "$date", avgRating:  $avg: '$rating' 
  ]).
  then(function (res) 
    console.log(res); 
  )

输出:

[
   _id: 'Aug 18, 2021', avgRating: 3.0212234706616727 ,
   _id: 'Aug 19, 2021', avgRating: 2.9680319680319682 ,
   _id: 'Aug 20, 2021', avgRating: 3.023976023976024 ,
   _id: 'Aug 17, 2021', avgRating: 2.9600665557404326 ,
   _id: 'Aug 21, 2021', avgRating: 3.072661217075386 
]

但是,如果我可以根据其他因素以某种方式过滤它,那就太好了。例如,每个帖子都有一个作者(参考用户模型)。我将如何根据作者的 country.name 或性别进行过滤?

用户模型:

const userSchema = new Schema(
email: 
    type: String,
    required: true,
    unique: true
,
birthday: 
    type: Date,
    required: true,
,
gender:
    type: String,
    required: true
,
country:
    name: 
        type: String,
        required: true
    ,
    flag: 
        type: String,
        // default: "/images/flags/US.png"
    
,
avatar: AvatarSchema,
displayName: String,
bio: String,
coverColor: 
    type: String,
    default: "#343a40"
,
posts: [ 
    
    type: Schema.Types.ObjectId,
    ref: "Post" 
    
],
comments: [
    
        type: Schema.Types.ObjectId,
        ref: "Comment"
    
],
postedToday: 
    type: Boolean,
    default: false
,
todaysPost: 
    type: String

) 

类似的东西

    Post.aggregate([
    $match: "date": today,
    $group: _id: "country": "$author.country.name", avgRating: $avg: "$rating"
]).then(function(res) 
    console.log(res)
)

【讨论】:

不确定我是否应该在单独的帖子中问这个问题?

以上是关于Mongoose/Mongodb Aggregate - 对多个字段进行分组和平均的主要内容,如果未能解决你的问题,请参考以下文章

无法与 Mongoose (Mongodb) 连接

Mongoose/MongoDb 收到错误 geoNear 不是函数

Mongoose (mongodb) 批量插入、删除、更新和无操作

详解node+mongoose+mongoDb(mongoDb安装运行,在node中链接)

唯一索引不适用于 Mongoose / MongoDB

从 Mongoose/MongoDB 中的数组中删除对象