Sample List retrieved
task one
task one (1)
true
task two
task two (5)
false
考虑到这种解决方法,让我们将_2711320变成一个Mongoose模型 .
mongoose.model('Task', TaskSchema);
var Task = mongoose.model('Task');
var ListSchema = new Schema({
name: String,
tasks: [Task.schema]
});
mongoose.model('List', ListSchema);
var List = mongoose.model('List');
var demoList = new List({name:'Demo List'});
var taskThree = new Task({name:'task three', priority:10});
var taskFour = new Task({name:'task four', priority:11});
demoList.tasks.push(taskThree.toObject(), taskFour.toObject());
demoList.save(function(err) {
if (err) {
console.log('error adding new list');
console.log(err);
} else {
console.log('new list successfully saved');
}
});
4 回答
简单来说,
model 是一个数据对象模型,就像您在MVC设计模式中找到的那样 . 它定义了 Structure 数据库中必须存储哪种数据以及数据具有什么类型的关系 .
schema 就像 database schema ,定义将存储在数据库中的内容 .
回答这类问题的最简单方法通常是举个例子 . 在这种情况下,有人已经为我做了:)
看看这里:
http://rawberg.com/blog/nodejs/mongoose-orm-nested-models/
EDIT: 原帖(如评论中所述)似乎不再存在,所以我在下面复制它 . 它是否应该返回,或者它刚刚移动,请告诉我 .
它给出了在mongoose中使用模型中的模式的正确描述以及为什么要这样做,并且还向您展示了如何通过模型推送任务,而模式是关于结构等的 .
Original Post:
让我们从一个在模型中嵌入模式的简单示例开始 .
我创建了一个新的
TaskSchema
对象,其中包含任务可能具有的基本信息 . Mongoose virtual attribute设置为方便地组合任务的名称和优先级 . 我这里只指定了一个getter,但也支持虚拟setter .我还定义了一个名为
isHighPriority
的简单任务方法来演示方法如何使用此设置 .在
ListSchema
定义中,您将注意到如何将tasks键配置为保存TaskSchema
对象的数组 . 任务键将成为DocumentArray的一个实例,它提供了处理嵌入式Mongo文档的特殊方法 .现在我只将
ListSchema
对象传递给mongoose.model并将TaskSchema保留了 . 从技术上讲,没有必要将TaskSchema
变成正式模型,因为我们不会将它保存在它自己的集合中 . 稍后我将向您展示如果您这样做不会造成任何伤害,它可以帮助您以相同的方式组织所有模型,尤其是当它们开始跨越多个文件时 .使用
List
模型设置,让我们添加几个任务并将它们保存到Mongo .我们的
List
模型(simpleList
)实例上的tasks属性就像常规JavaScript数组一样,我们可以使用push向它添加新任务 . 需要注意的重要事项是将任务添加为常规JavaScript对象 . 这是一个微妙的区别,可能不会立即直观 .您可以从Mongo shell验证新列表和任务已保存到mongo .
现在我们可以使用
ObjectId
来拉出Sample List
并迭代其任务 .如果你运行最后一段代码,你会收到一个错误,说嵌入文档没有方法
isHighPriority
. 在当前版本的Mongoose中,您无法直接访问嵌入式架构上的方法 . 有一个open ticket来修复它,在向Mongoose谷歌集团提出问题后,manimal45发布了一个有用的解决方案,现在就可以使用了 .如果您运行该代码,您应该在命令行上看到以下输出 .
考虑到这种解决方法,让我们将_2711320变成一个Mongoose模型 .
TaskSchema
定义与之前相同,因此我将其删除了 . 一旦它变成模型,我们仍然可以使用点表示法访问它的底层Schema对象 .让我们创建一个新列表并在其中嵌入两个Task模型实例 .
当我们将Task模型实例嵌入到List中时,我们在它们上面调用
toObject
将它们的数据转换为List.tasks
DocumentArray
期望的纯JavaScript对象 . 以这种方式保存模型实例时,嵌入的文档将包含ObjectIds
.完整的代码示例是available as a gist . 希望这些解决方案有助于在Mongoose继续发展的过程中顺利完成任务 . 我仍然是Mongoose和MongoDB的新手,所以请随时在评论中分享更好的解决方案和技巧 . 快乐的数据建模!
Schema 是一个对象,它定义将存储在MongoDB集合中的任何文档的结构;它使您可以为所有数据项定义类型和验证器 .
Model 是一个对象,使您可以轻松访问命名集合,从而允许您查询集合并使用模式验证保存到该集合的任何文档 . 它是通过组合Schema,Connection和集合名称创建的 .
最初由Valeri Karpov表达,MongoDB Blog
我没有解释为什么Mongoose决定要求开发人员同时提供Schema和Model变量 . 他们已经消除了一个框架的例子开发人员需要定义数据模式是django - 开发人员在models.py文件中编写他们的模型,并将其留给框架来管理模式 . 考虑到我对django的经验,首先想到他们为什么这样做的原因是易于使用 . 也许更重要的是DRY(在更改模型时必须记住更新架构 - django会为你做到这一点!Rails还为你管理数据架构 - 开发人员不编辑直接架构,但通过定义操纵架构的迁移来更改它 .
我可以理解Mongoose将模式与模型分开的一个原因是您希望从两个模式构建模型的实例 . 这样的场景可能会引入比值得管理更多的复杂性 - 如果您有两个由一个模型管理的模式,为什么它们不是一个模式?
也许原始问题更像是传统关系数据库系统的遗留物 . 在世界NoSQL / Mongo世界中,模式可能比MySQL / PostgreSQL更灵活,因此更改模式是更常见的做法 .