Add a specific data structure to mongoose Schema in NodeJs

Viewed 27

I have a star rating system for users, and I want to save the count for each star in my User schema. For example 5 stars have 3 count, 2 stars have 0 count and I want to save that in the following structure:

{ 5: 3, 2: 0, ... }

I am struggling to add a dynamic key to my mongoose Structure

Here is my alternative approach in my user model:

ratingCount: {
  type: [
    {
      rating: {
      type: String,
      enum: [5, 4, 3, 2, 1],
    },
    count: Number,
  },
],

},

If there is no alternative to my approach, I can modify it in the FE. But another approach will make it easier.

Thank you.

1 Answers

I don't think my answer is the answer to your specific question, but I think it might be useful. To solve this problem it would be enough to use the index of an array as if it were the number of stars. For example, adding the ratingCount field to the schema like so:

ratingCount: {
  type: [Number],
  default: [0, 0, 0, 0, 0, 0],
  required: true
}

So, ratingCount[1] will be the number of ratings received with one star, ratingCount[2] will be the number of ratings received with two stars and so on.

We then need to build the functions to use this system. For example, the function to vote a user (simplified):

async function rateUser(req, res) {
  try {
    if (req.body.email == null || req.body.numberOfStars == null)
      return res.status(400).json({
        msg: ['Missing data.']
      });
    switch (req.body.numberOfStars) {
      case 1:
        await User.updateOne({ email: req.body.email }, { $inc: { 'ratingCount.1': 1 } });
        break;
      case 2:
        await User.updateOne({ email: req.body.email }, { $inc: { 'ratingCount.2': 1 } });
        break;
      case 3:
        await User.updateOne({ email: req.body.email }, { $inc: { 'ratingCount.3': 1 } });
        break;
      case 4:
        await User.updateOne({ email: req.body.email }, { $inc: { 'ratingCount.4': 1 } });
        break;
      case 5:
        await User.updateOne({ email: req.body.email }, { $inc: { 'ratingCount.5': 1 } });
        break;
      default:
        return res.status(403).json({
          msg: ['Invalid data.']
        });
    }
    res.status(200).json({
      msg: ['Done.']
    });
  } catch (err) {
    res.status(500).json({
      msg: ['Problem with the request.']
    });
  }
}
Related