1

I'm trying to calculate an average value based on the user's rating for the product.

My Schemas:

const journalSchema = new mongoose.Schema({
  title: String,
  category: String,
  subcategory: String,
  review: [{type: mongoose.Schema.Types.ObjectId, ref: 'Review'}],
  link: String,
  description: String,
  subscribers: Number,
  image: String
});

const reviewSchema  = new mongoose.Schema({
  author: {type: mongoose.Schema.Types.String, ref: 'User'},
  content: String,
  date: Date,
  rating: {type: Number, min: 1.0, max: 5.0}
});

const Journal = mongoose.model("Journal", journalSchema);
const Review = mongoose.model("Review", reviewSchema);

Route:

app.get("/", function(req, res){
Journal.find({}, function(err, journals){
  if(err){
    console.log(err);
  }
  else{
      Review.aggregate([
        {$unwind: "$journals"},
        {$match: {_id: {$in: journals}}},
        {$unwind: "$journals.review"},
        {$group: {_id: journals.review, average: {$avg: "$rating"}}}
      ], function(err, results){
        if(err){
          console.log(err);
        }
        else{
          console.log(results);
        }
      })
    res.render("home", {journals: journals});
    }
  });
});

All I get is an empty array.

My goal is to render the page with shops that have a rating above 4. I can't figure out where the issue is. Is it possible to achieve this with other alternatives or using aggregate is the way to go?

0

1 Answer 1

1

You can use the aggregation method,

  • $lookup with reviews collection
  • $avg to get average of rating from reviews result
  • $match to filter journals by rating should greater than 4
app.get("/", function(req, res) {
  Journal.aggregate([
    {
      $lookup: {
        from: "reviews",
        localField: "review",
        foreignField: "_id",
        as: "review"
      }
    },
    {
      $addFields: { review: { $avg: "$review.rating" } }
    },
    {
      $match: {
        review: { $gt: 4 }
      }
    }
  ], 
  function(err, results) {
    if(err) { console.log(err); }
    else { 
      res.render("home", { journals: results });
    }
  })
});

Playground

Sign up to request clarification or add additional context in comments.

5 Comments

Still getting an empty array :(
make sure the conneted database is correct and collection name reviews is correct. debug step by step, by removing stages from pipeline, otherwise we can't help by just this information Still getting an empty array
I have another schema for users which I referenced in the review schema to get the user's username, is it possible that it might be causing the problem?
no, you just need to debug query, 1) try by just no pipeline stage Journal.aggregate([] 2) try by first $lookup stage etc.
So I removed the $match part, and instead checked the average in the ejs file and now it works, not sure if it's a good way to do it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.