聚集猫鼬模式并将平均值保存到数据库

时间:2020-03-01 18:16:30

标签: mongodb mongoose mern

在节点应用程序上工作的功能之一是让用户创建配方。

使用邮递员,我可以成功创建,获取等。我想汇总RecipeSchema上的评分,并简单地计算出开始构建时在前端显示的平均值。

我能够获得评分的平均值,但无法将其保存到数据库中。寻找有关如何执行此操作的建议。我的架构如下...

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const RecipeSchema = new Schema({
  user: {
    type: Schema.Types.ObjectId,
    ref: 'user'
  },
  name: {
    type: String,
    required: true
  },
  avatar: {
    type: String
  },
  title: {
    type: String,
    trim: true,
    required: [true, 'Please add a title for recipe']
  },
  description: {
    type: String,
    required: [true, 'Please add a description for recipe']
  },
  servings: {
    type: Number,
    required: [true, 'Please add number of servings recipe will make']
  },
  prepTime: {
    type: Number,
    required: true,
    min: 0,
    max: 59,
    required: true
  },
  cookTime: {
    type: Number,
    required: true
  },
  image: {
    type: String,
    default: 'no-photo.jpg'
  },
  ingredients: [
    {
      ingredient: {
        type: String,
        required: true
      },
      amount: {
        type: Number,
        required: true
      }
    }
  ],
  directions: [
    {
      step: {
        type: Number,
        required: true
      },
      direction: {
        type: String,
        required: true
      }
    }
  ],
  ratings: [
    {
      user: {
        type: Schema.Types.ObjectId,
        ref: 'users'
      },
      rating: {
        type: Number,
        min: 1,
        max: 10
      }
    }
  ],
  avgRating: {
    type: Number
  },
  comments: [
    {
      user: {
        type: Schema.Types.ObjectId,
        ref: 'users'
      },
      text: {
        type: String,
        required: true
      },
      name: {
        type: String
      },
      avatar: {
        type: String
      },
      date: {
        type: Date,
        default: Date.now
      }
    }
  ],
  date: {
    type: Date,
    default: Date.now
  }
});

起初,我尝试使用“ $ unwind”猫鼬方法查看评分并尝试获取平均值。看来使用'$ match'然后使用'$ project'可以得到平均值,并且我可以console.log结果。

// Get the average recipe rating
RecipeSchema.statics.getAverageRating = async function(recipe) {
  const obj = await this.aggregate([
    {
      $match: { recipe: recipe }
    },
    {
      $project: {
        avgRating: { $avg: '$ratings.rating' }
      }
    }
  ]);

  try {
    console.log(
      `Average Rating for recipe ${obj[0]._id} is: ${obj[0].avgRating}`
    );
    await this.model('recipe').findByIdAndUpdate(recipe, {
      avgRating: obj[0].avgRating
    });
  } catch (err) {
    console.error(err);
  }
};

// Call getAverageRating after save
RecipeSchema.post('save', function() {
  this.constructor.getAverageRating(this.avgRating);
});

RecipeSchema.pre('remove', async function() {
  await this.constructor.getAverageRating(this.avgRating);
});

module.exports = mongoose.model('recipe', RecipeSchema);

该帖子未更新数据库。有什么建议吗?

向数据库发送新配方后的控制台

{ id: '5e5bf09722a495afe703590e', iat: 1583083680, exp: 1585675680 }
Promise { <pending> }
POST /api/v1/recipes 201 421.186 ms - 1495
Average Rating for recipe 5e5bf809502395fe13da95c4 is: 7.333333333333333
[nodemon] restarting due to changes...
[nodemon] starting `node server.js`
Server is running in development mode on PORT:8080
MongoDB Connected cluster0-shard-00-00-6tjes.mongodb.net

0 个答案:

没有答案