mongoose如何pipe理在一个参考文件计数

所以我有这些模式:

'use strict'; /** * Module dependencies. */ var mongoose = require('mongoose'), Schema = mongoose.Schema; /** * Comment Schema */ var CommentSchema = new Schema({ post_id: { type: Schema.Types.ObjectId, ref: 'Post', required: true }, author:{ type: String, required: true }, email:{ type: String, required: true }, body: { type: String, required: true, trim: true }, status: { type: String, required: true, default: 'pending' }, created: { type: Date, required: true, default: Date.now }, meta: { votes: Number } }); /** * Validations */ CommentSchema.path('author').validate(function(author) { return author.length; }, 'Author cannot be empty'); CommentSchema.path('email').validate(function(email) { return email.length; }, 'Email cannot be empty'); CommentSchema.path('email').validate(function(email) { var emailRegex = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/; return emailRegex.test(email); }, 'The email is not a valid email'); CommentSchema.path('body').validate(function(body) { return body.length; }, 'Body cannot be empty'); mongoose.model('Comment', CommentSchema); 'use strict'; /** * Module dependencies. */ var mongoose = require('mongoose'), monguurl = require('monguurl'), Schema = mongoose.Schema; /** * Article Schema */ var PostSchema = new Schema({ title: { type: String, required: true, trim: true }, author:{ type: String, required: true, default: 'whisher' }, slug: { type: String, index: { unique: true } }, body: { type: String, required: true, trim: true }, status: { type: String, required: true, trim: true }, created: { type: Date, required: true, default: Date.now }, published: { type: Date, required: true }, categories: { type: [String], index: { unique: true } }, tags: { type: [String], required: true, index: true }, comment: { type: Schema.Types.ObjectId, ref: 'CommentSchema' }, meta: { votes: Number } }); /** * Validations */ PostSchema.path('title').validate(function(title) { return title.length; }, 'Title cannot be empty'); PostSchema.path('body').validate(function(body) { return body.length; }, 'Body cannot be empty'); PostSchema.path('status').validate(function(status) { return /publish|draft/.test(status); }, 'Is not a valid status'); PostSchema.plugin(monguurl({ source: 'title', target: 'slug' })); mongoose.model('Post', PostSchema); 

由一个API我查询后像

 exports.all = function(req, res) { Post.find().sort('-created').exec(function(err, posts) { if (err) { res.jsonp(500,{ error: err.message }); } else { res.jsonp(200,posts); } }); }; 

如何检索有多less评论的post? 我的意思是我想要像post.ncomments这样的后期对象的额外的礼仪。

我想到的第一件事是添加一个额外的领域的后架构和更新每当用户添加评论

 meta: { votes: Number, ncomments:Number } 

但我觉得这似乎很难看

如果你想要最有效的解决scheme,那么在Post模式中手动添加一个像number_comments这样的字段可能是最好的办法,特别是如果你想要在多个post上进行操作(比如基于评论的sorting)。 即使您使用索引进行计数,也不可能像预先计算的那样有效(最终,如果您已经预先计算,则可以执行更多types的查询没有selectembedded评论)。

 var PostSchema = new Schema({ /* others */ number_comments: { type: Number } }); 

更新号码:

 Post.update({ _id : myPostId}, {$inc: {number_comments: 1}}, /* callback */); 

另外,除非将其用作“最近”样式字段(或者只有一个字段),否则在PostSchema不需要comment字段。 在Comment模式中有一个Post引用的事实足以查找给定Post所有Comment

 Comments.find().where("post_id", myPostId).exec(/* callback */); 

你想确保该字段是索引。 正如你可以使用这个populate这个字段的ref ,你可能会考虑将这个字段重命名为"post"

 Comments.find().where("post", myPostId).exec(/* callback */); 

你仍然只能将post字段设置为post_id (而不是实际的Post对象实例)。

您也可以select在Postembedded评论。 在MongoDB网站上有关于这些select的一些很好的信息 。 请注意,即使embedded了注释,您也需要将整个数组重新计数。

它看起来像你的Post模式将只允许一个单一的评论:

 // .... comment: { type: Schema.Types.ObjectId, ref: 'CommentSchema' }, // .... 

其中一个考虑就是将您的评论作为子文档存储在您的post中,而不是存储在自己的collections中。 一般而言,您是否只会在与相关post相关的问题上查询您的意见,或者您是否经常独立于post查看所有意见?

如果您将注释移至子文档,则可以执行诸如post.comments.length类的post.comments.length

但是,如果您将注释保留为单独的集合(NoSQL DB中的关系结构 – 有时候有这样做的理由),那么就没有自动的方法。 Mongo不能连接,所以你必须发出第二个查询。 你有几个select如何做到这一点。 一个是你的post实例的实例方法。 你也可以做一个手动的CommentSchema.count({postId: <>})

你提出的解决scheme也是完全有效的。 这个策略被用在可以进行连接的关系数据库中,因为它比每次计算所有的评论会有更好的performance。