我是Node.js和Mongoose库的新手。我的问题是我有两个集合模式
我试图在reviews_count
集合中添加一个虚拟字段(Restaurent
)来进行评论计数。
如何实现这一目标?猫鼬有任何特定功能吗?
Restaurant: Reviews:
_id: ObjectId restaurent_id: (Restaurant ref id)
name: String review: String
我希望在尝试获取餐厅详细信息时得到输出。
{
"_id": "2344....",
"name": "Restaurant name".
"reviews_count": 220
}
答案 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()函数,如果这样做没有太大帮助,则可以采用我概述的前两种方法之一。>