首页 > 解决方案 > Mongoose/Mongodb Aggregate - 对多个字段进行分组和平均

问题描述

我有一个带有 2 个字段的 Post 模型:日期和评级。我将如何获得每个日期的平均总评分?因此,首先按日期分组,然后在该日期的所有帖子中平均评分。我需要在猫鼬中做到这一点,但他们的文档很难理解。

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"]); 
  })

标签: mongodbmongooseaggregate

解决方案


这对我有用:

  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)
})

推荐阅读