猫鼬中是否有可用的功能来访问总计数功能?

时间:2018-12-21 05:25:48

标签: node.js mongoose

我是Node.js和Mongoose库的新手。我的问题是我有两个集合模式

  1. 餐厅
  2. 评论

我试图在reviews_count集合中添加一个虚拟字段(Restaurent)来进行评论计数。

如何实现这一目标?猫鼬有任何特定功能吗?

    Restaurant:                      Reviews:

    _id: ObjectId                   restaurent_id: (Restaurant ref id)
    name: String                    review: String

我希望在尝试获取餐厅详细信息时得到输出。

{
  "_id": "2344....",
  "name": "Restaurant name".
  "reviews_count": 220
 }

1 个答案:

答案 0 :(得分:1)

是的,这是可能的。有很多方法可以执行此操作:您实际上可以定义一个异步虚拟对象,该虚拟对象将查询Reviews,但是我不太喜欢这种方法,因为您必须确保等待它或处理回调,难闻的气味:

const count = await restaurant.reviews

或者,您可以只定义一个instance method这样的东西(异步会更好,更困难),我更喜欢它,因为调用此函数时它使代码更易于阅读:

  // assign a function to the "methods" object of your restaurant schema
  restaurant.methods.getReviews = function(cb) {
    return this.model('Reviews').find({ restaurant_id: this._id }, cb);
  };

最后,还有第三种,我认为是最佳选择:虚拟填充 Mongoose 4.5引入了此功能,非常适合您的用例。像这样定义您的字段:

Restaurant.virtual('reviews', {
  ref: 'Reviews',
  localField: '_id',
  foreignField: 'restaurant_id'
});

然后像这样查询它:

Restaurant.findOne().populate('reviews').exec(function(error, reviews) {
  // `reviews.count` is the virtual you are looking for
});

这是最干净,功能最全的解决方案,因为它使您不必不必要地向主对象添加带有引用的数组,并且仍然可以轻松访问餐厅的所有评论。您可以在这里找到一篇不错的文章: http://thecodebarbarian.com/mongoose-virtual-populate

注意:此解决方案可能会给您带来性能问题,因为我们总是查询整个审阅文档,而不仅仅是查询计数。如果您觉得这可能是个问题,则可能需要先向查询中添加.lean()函数,如果这样做没有太大帮助,则可以采用我概述的前两种方法之一。