mongooseJS关系

所以我正在制作一个具有用户模型和后期模型的快速应用程序。 用户有很多post,每个post都属于一个用户。 这里是模型

user.js的

var mongoose = require('mongoose'); var Schema = mongoose.Schema; var userSchema = new Schema({ _id : Number, username: String, password: String, admin: Boolean, posts: [{ type: Schema.Types.ObjectId, ref: 'Post' }] }); module.exports = mongoose.model('User', userSchema); 

post.js

 var mongoose = require('mongoose'); var Schema = mongoose.Schema; var postSchema = new Schema({ title: 'string', content: 'string', _author: { type: Number, ref: 'User' } }); module.exports = mongoose.model('Post', postSchema); 

首先,我不确定这是不是最好的方式来关联这两个模型,以便后者属于用户,但这是在这里的mongoose文档看起来像http://mongoosejs.com/docs/populate.html

现在我想要做的是当我打这条路线

 router.post('/', function(req, res){ var post = new Post(req.body); console.log(author.posts); post.save(function(err){ if (err){ return res.send(err); } res.send({message: 'Post added!'}); }); }); 

我想要将post插入到用户post数组中。 我一直在查看文档,并认为填充方法是做到这一点,但我似乎无法弄清楚如何使用它,如果它实际上插入到作者职位数组。

我试过,但似乎没有做我想要的

 Post.findOne({ title: "The nip" }) .populate('_author') .exec(function (err, post) { if (err) return handleError(err); console.log('The creator is %s', post._author.username); }); 

任何关于如何将创build的post转移到其作者post数组的build议将非常感谢!

populate()不保存任何东西。 它是基于读取的function,用于search您正在填充的_id ,并将其附加到您刚才查询的mongoose文档。 所有这一切都是保存你第二个查询来find用户。 没有什么是真正的保存。

在devise方面,我甚至不打算在用户的post数组,因为它有可能无限增长。 在实际的应用程序中,在任何给定的时间,你已经有内存中的用户或者post,所以你已经有了他们的objectId (就像Rob说的,不要使用Number )。 如果你有用户,你可以find他们的post:

Post.find({_author: author._id}, callback)

同样如果你有这个post,你可以find这个用户:

User.findOne({_id: post._author}, callback)

如果您手头没有任何一个,并且您的应用程序定期通过作者的用户名searchpost,则可以将其添加到post架构中,并将其发送到您的保存请求中。 这样您可以通过作者轻松searchpost。 将发布模式切换到:

 var postSchema = new Schema({ title: String, content: String, _author: { _id: { type: Schema.ObjectId, ref: 'User' }, username: String } }); 

你的查询将是:

 Post.find({"_author.username", username}, callback) 

重复数据完全可以。 应用程序通常读取的内容比他们写的要多,所以在编写时多花些功夫来节省阅读时间是值得的。

我认为这样做的mongoose-y方式将是前/后中间件。 例如,在保存post时,您可以configurationmongoose以自动保持用户集合同步,如下所示:

post.js

 var User = mongoose.model('User'); postSchema.pre('save', function(next) { // Don't do anything unless this is a new Post being created // If a Post's author can be changed you would also need to check for that here if (!this.isNew) { return next(); } User.update({_id: this._author}, { $push: {posts: this._id} }) .then(function() { next(); }) .then(null, function(err) { // Whoops! Something broke. You may want to abort this update. next(err); }); }); 

您也可以设置类似的postSchema.post('remove', ...)中间件来执行级联删除。

有几件事要注意:

1)调用mongoose.model只有一个像我上面的参数将加载模型,而不是定义它。 使用它来让模型相互引用。 如果你使用节点module.exports你可能会得到循环依赖。

2)遵循@ Rob关于ObjectId的build议。 除非您有充分的理由,否则不要将您的ID改为Number。