Search code examples
node.jsmongodbexpressaggregation-frameworkaverage

Get average rate for product comments in MongoDB and Express


I want to calculate average rating for products based on comments rate, exactly I want to return products object with one more property in response when client call get all product api

my product schema is like below, thank you in advance.

const mongoose = require("mongoose");
const { s, rs, n, rn, ref, rref } = require("../utils/mongo");

let commentSchema = new mongoose.Schema(
  {
    user: rref("user"),
    body: rs,
    rate: {
      ...n,
      default: 0,
      enum: [0, 1, 2, 3, 4, 5],
    },
  },
  { timestamps: true }
);

let schema = new mongoose.Schema(
  {
    user: rref("user"),
    name: rs,
    description: s,
    images: [s],
    price: rn,
    discount: n,
    sizes: [sizeSchema],
    categories: [ref("category")],
    tags: [s],
    comments: [commentSchema],
    rating: n,
    inStock: {
      type: Boolean,
      default: true,
    },
    stock: n,
    sold: {
      ...n,
      default: 0,
    },
    view: {
      ...n,
      default: 0,
    },
  },
  { timestamps: true }
);

module.exports = mongoose.model("product", schema);

I want to return in response something like this:

let result = [
 {
   name: 'product name', 
   comments: [
      {
        user: "2a2sdw22das5262123223",
        body: "good product",
        rate: 4
      },
      {
        user: "2a2sdw22das5262123223",
        body: "good product",
        rate: 2
      }
   ], 
   avgRate: 2, // how to calculate this?
   price: 20
   ...
 }
]


Solution

  • You can use aggregation pipeline to do that, it will add the avgRating field avgRate which you can use for future ref:

    db.collectionName.aggregate([{ $addFields : { avgRate: { $avg: "$comments.rate"} } }])