使用 Mongoose 更新评论系统平均评分的正确方法

Posted

技术标签:

【中文标题】使用 Mongoose 更新评论系统平均评分的正确方法【英文标题】:Proper way of updating average rating for a review system using Mongoose 【发布时间】:2021-01-19 19:52:38 【问题描述】:

我目前正在使用 Udemy 课程学习一些后端内容,并且我有一个示例网站,可让您添加露营地(露营地名称、图片、描述等)并查看它们。我正在使用 Node.js 的 Express 框架和 Mongoose 来访问数据库。

我的露营地架构如下所示:

const campgroundSchema = new mongoose.Schema(
    name: String,
    image: String,
    description: String,
    price: String,
    comments: [
        
            type: mongoose.Schema.Types.ObjectId,
            ref: "Comment"
        
    ],
    rating: type: Number, default: 0
);

我的评论/评论架构如下所示:

const commentSchema = new mongoose.Schema(
    text: String,
    rating: 
        type: Number,
        min: 1,
        max: 5,
        validate: validator: Number.isInteger
    ,
    campground: type: mongoose.Schema.Types.ObjectId, ref: "Campground"
);

Campgrounds 和 Comments 也有对 User 的引用,但为简单起见,我将其省略了。

我希望了解更新和显示露营地平均评分的最佳做法。

我所遵循的教程使用的方法是在每次添加、更改或删除评论时重新计算平均评分。以下是新评论的工作方式:

Campground.findById(campgroundId).populate("comments").exec(function(err, campground) 
    Comment.create(newComment, function(err, comment) 
        campground.comments.push(comment);
        campground.rating = calculateRating(campground.comments);
        campground.save();
    );
);

“calculateRating”遍历评论数组,得到总和,返回总和除以cmets个数。

我的直觉告诉我应该有办法让 Campground 的“评分”字段执行“calculateRating”功能的功能,这样我就不必每次添加评论时都更新评分、更改或删除。我一直在研究文档有一段时间了,但是由于我对 Mongoose 和一般数据库还很陌生,所以我对如何进行有点迷茫。

总而言之:我想向我的 Campground 模型添加功能,以便当我访问它的评分时,它会自动访问 cmets 数组中引用的每个评论,总结它们的评分,并返回平均值。

如果我的任何术语不正确,我深表歉意。非常感谢任何关于我将如何实现这一目标的提示!

爱,

卡尔

【问题讨论】:

【参考方案1】:

我认为您尝试做的是获取文档的虚拟属性,该属性获得平均评分,但不会持久保存到 mongo 数据库。 根据 mongoosejs :- Virtuals 是您可以获取和设置但不会持久保存到 MongoDB 的文档属性。它们设置在架构上。 你可以这样做:

CampgroundSchema.virtual('averageRating').get(function() 
  let ratings = [];
  this.comments.forEach((comment) => ratings.push(comment.rating));
  return (ratings.reduce((a,b)=>a+b)/ratings.length).toFixed(2);
 );

找到露营地或露营地后,在您的视图引擎上,您只需要调用 ; campground.averageRating;

在这里阅读更多:https://mongoosejs.com/docs/guide.html#virtuals

还请注意,您不能对虚拟属性进行任何类型的查询。

【讨论】:

以上是关于使用 Mongoose 更新评论系统平均评分的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

用 PHP 计算总平均评分

Flutter - 带有 SmoothStarRating 和 Rest API 的评分和评论系统

在 SQL 中平均电影评分

如何使用计算值批量更新 MongoDB 中服务器上的文档?

Node JS mongoose 创建博文评论系统

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