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。