如何使用 Mongoose 创建遵循模型的嵌入式文档?
Posted
技术标签:
【中文标题】如何使用 Mongoose 创建遵循模型的嵌入式文档?【英文标题】:How to create an embedded document that follows a model with Mongoose? 【发布时间】:2016-09-28 23:33:42 【问题描述】:我有两个模型,Post
和 Comment
:
我的Post
模型(models/post.js
):
var mongoose = require('mongoose');
var Comment = require('../models/comment');
var Schema = mongoose.Schema;
module.exports = mongoose.model('Post', new Schema(
text: type: String, trim: true,
postedBy: String,
comments: [Comment]
));
我的Comment
模型(models/comment.js
):
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
module.exports = mongoose.model('Comment', new Schema(
user: String,
comment: type: String, trim: true,
created: type: Date, default: Date.now(), select: false
));
当我尝试创建一个没有任何comments
的新帖子时,帖子创建得非常好。
虽然当我在创建后尝试$push
对帖子发表评论时,没有任何反应。
Post.findOneAndUpdate(
"_id": req.params.id,
$push: comments:
comment: "Hello World",
user: "933ujrfn393r"
).exec(function(err, post)
console.log(post);
res.json(success: true);
);
为什么无法将评论推送到帖子?我的console.log(post)
行只记录undefined
,所以不太清楚这里发生了什么。我尝试了Post.findOne("_id": req.params.id)
的简单测试,它成功返回了帖子,所以find查询没有问题。
【问题讨论】:
不要为此使用两个不同的集合,而是使用单个集合,在该集合中,您可以分别为字段 cmets 定义架构。 【参考方案1】:基于this question,我相信您的问题是您嵌入的是Comment
Model 而不是Comment
Schema。
尝试将post.js
更改为:
var Comment = require('../models/comment');
到:
var Comment = require('../models/comment').schema;
查看 Mongoose docs 关于子文档的示例后,这也很有意义。
附:
帮助我调查此问题的是输出exec
回调的err
对象以查看实际发生的情况...
【讨论】:
这可行,但创建模型也会在数据库中创建一个单独的集合。如果您不使用模型,那么首先从模式中实例化模型是没有意义的。【参考方案2】:内嵌子文档
您的使用意味着模型中嵌入了sub document,它只需要为子文档定义schema。这会将两个模式存储在 MongoDB 的单个集合中的单个文档中
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var CommentSchema = new Schema(
user: String,
comment: type: String, trim: true,
created: type: Date, default: Date.now(), select: false
);
var PostSchema = new Schema(
text: type: String, trim: true,
postedBy: String,
comments: [CommentSchema]
);
module.exports = mongoose.model('Post', PostSchema);
然后像你一样创建 cmets。
Post.findOneAndUpdate(
"_id": req.params.id,
$push: comments:
comment: "Hello World",
user: "933ujrfn393r"
).then(function (post)
console.log(post);
res.json(success: true);
);
文档参考
如果您想保留这两个模型,则需要在 Post
架构中使用引用。这将在 MongoDB 的单独集合中创建单独的文档,并使用 _id
查找第二个文档。
var PostSchema = new Schema(
text: type: String, trim: true,
postedBy: String,
comments:
type: mongoose.Schema.Types.ObjectId,
ref: 'Comment'
);
然后需要创建 cmets 才能在 Post
模型中引用它们。
c = new Comment( comment: 'x' )
c.save().then(function (result)
return Post.findOneAndUpdate(
_id: req.params.id ,
$push: comments: result._id
);
).then(function (result)
console.log('updated post');
);
Population 可用于轻松检索“外来”文档。
【讨论】:
如果使用您提到的第一种方法(每种方法不同,尽管文档相同),我将如何将评论保存到 post 文档?我尝试创建新评论,例如c = new Comment( comment: 'x' )
,然后将$push
ing 到Post
,虽然它似乎没有推动任何东西......
new Comment
仅适用于 Comment
是模型的第二种方法。当 cmets 只是一个 Schema 和嵌入式文档时,查询应该像您在问题中那样工作。请注意,模式和模型在 Mongoose 中是分开的。以上是关于如何使用 Mongoose 创建遵循模型的嵌入式文档?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Mongoose 中更改文档子数组的对象内的布尔值?
如何在不创建 Mongoose 模型的情况下将 GraphQL 与 Mongoose 和 MongoDB 一起使用