我正在学习猫鼬。目前,我没有做过很多不错的事情,但是我真的不完全了解Mongoose如何管理架构之间的关系。
所以,简单的事情(我希望)是:我正在做一个经典的练习(我自己,因为我找不到能创建两个以上架构的优秀教程),其中包含3个架构:
用户,帖子,评论。
我不觉得这很困难吗?
目前,我可以很好地处理用户与帖子之间的关系。我正在使用mongo-relation时,我的单元测试恰好返回了我需要的结果,我不知道这是否是个好主意...
it('Use should create a Post', function(done) {
User.findOne({ email: '[email protected]' }, function(err, user) {
var post = {
title: 'Post title',
message: 'Post message',
comments: []
};
user.posts.create(post, function(err, user, post) {
if (err) return done(err);
user.posts[0].should.equal(post._id);
post.author.should.equal(user._id);
// etc...
done();
});
});
});
现在的问题是创建评论。我无法创建同时引用帖子和用户的评论。
我做了类似的事情并且可以工作,但是当我执行remove
它时,它只会从帖子中删除,而不会从用户中删除。
因此,我认为有些事情我想念的,或者我仍然需要学习以增强它。
it('User should add a Comment to a Post', function(done) {
User.findOne({ email: '[email protected]' }, function(err, user) {
if (err) return done(err);
var comment = new Comment({
author: user._id,
message: 'Post comment'
});
Post.findOne({ title: 'Post title'}, function(err, post) {
if (err) return done(err);
post.comments.append(comment, function(err, comment) {
if (err) return done(err);
post.save(function(err) {
if (err) return done(err);
});
comment.author.should.equal(user._id);
post.comments.should.have.length(1);
// etc...
done();
});
});
});
});
如您所见,代码不是很“好看”,但是就创建而言,它可以很好地工作。
问题是当我删除评论时。好像有问题。
这是模型关系:
// User Schema
var userSchema = new mongoose.Schema({
// [...],
posts: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Post' }],
comments: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Comment' }],
});
// Post Schema
var postSchema = new mongoose.Schema({
author: { type: mongoose.Schema.ObjectId, ref: 'User', refPath: 'posts' },
title: String,
message: String,
comments: [{ type: mongoose.Schema.ObjectId, ref: 'Comment' }]
});
// Comment Schema
var commentSchema = new mongoose.Schema({
author: { type: mongoose.Schema.ObjectId, ref: 'User', refPath: 'comments' },
post: { type: mongoose.Schema.ObjectId, ref: 'Post', refPath: 'comments' },
message: String
});
我真的希望您能帮助您理解所有这一切。
一个很好的简单教程也不错。
我认为您是对子文档的误解。建立架构的方式是创建对其他集合中文档的引用。
例如,如果您创建一个帖子,则在数据库中它将如下所示:
{
"author": ObjectId(123),
"title": "post title",
"message": "post message",
"comments": [ObjectId(456), ObjectId(789)]
}
请注意,“作者”字段仅包含创建它的作者的ID。它实际上并不包含文档本身。
从数据库读取文档时,可以使用猫鼬的“填充”功能来获取所引用的文档。
防爆(填充):
Post
.findOne({ title: 'Post title'})
.populate('author', function(err, post) {
// this will print out the whole user object
console.log(post.author)
});
防爆(无填充):
Post
.findOne({ title: 'Post title'}, function(err, post) {
// this will print out the object ID
console.log(post.author)
});
子文档:
您实际上可以使用子文档将数据嵌套在数据库中,该架构看起来会稍有不同:
var postSchema = new mongoose.Schema({
author: { userSchema },
title: String,
message: String,
comments: [commentSchema]
});
保存帖子时,用户文档将嵌套在帖子中:
{
"author": {
"name": "user name",
"email": "[email protected]"
...
},
"title": "post title",
"message": "post message",
"comments": [{
"message": "test",
...
}, {
"message": "test",
...
}]
}
子文档在mongo中很有用,但在这种情况下可能没有用,因为您将在每个帖子中复制所有用户数据。
移除文件
当您发布Comment.remove(id)时,该注释将被删除,但不会影响引用该注释的其他文档。因此,您将拥有一个帖子和一个用户,该用户的评论ID不存在。您需要手动清除其他文档中的注释ID。您可以使用mongoose pre remove事件来执行此操作。http://mongoosejs.com/docs/middleware.html
commentSchema.pre('remove', function (next) {
// this refers to the document being removed
var userId = this.author;
var postId = this.post;
User.findById(userId, function(err, user) {
// remove comment id from users.comments here;
Post.findById(postId, function(err, post) {
// remove comment id from post.comments;
next();
});
});
});
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句