gpt4 book ai didi

mongodb - 为什么 Mongoose 同时具有模式和模型?

转载 作者:太空宇宙 更新时间:2023-11-04 02:04:56 24 4
gpt4 key购买 nike

这两种类型的对象看起来是如此接近,以至于两者都显得多余。同时拥有模式和模型有什么意义?

最佳答案

回答此类问题的最简单方法通常是举一个例子。在这种情况下,某人已经为我完成了:)

在这里看看:

http://rawberg.com/blog/nodejs/mongoose-orm-nested-models/

编辑:原始帖子(如评论中所述)似乎不再存在,所以我在下面复制它。如果它返回了,或者它刚刚移动了,请告诉我。

它很好地描述了在猫鼬中的模型中使用模式的原因,以及您为什么要这样做,并向您展示了当模式与结构等有关时如何通过模型推送任务。

原始帖子:

让我们从一个将模式嵌入模型中的简单示例开始。

var TaskSchema = new Schema({
name: String,
priority: Number
});

TaskSchema.virtual('nameandpriority')
.get( function () {
return this.name + '(' + this.priority + ')';
});

TaskSchema.method('isHighPriority', function() {
if(this.priority === 1) {
return true;
} else {
return false;
}
});

var ListSchema = new Schema({
name: String,
tasks: [TaskSchema]
});

mongoose.model('List', ListSchema);

var List = mongoose.model('List');

var sampleList = new List({name:'Sample List'});


我使用任务可能具有的基本信息创建了一个新的 TaskSchema对象。设置了猫鼬 virtual attribute以方便地组合任务的名称和优先级。我在这里只指定了一个吸气剂,但也支持虚拟的吸气剂。

我还定义了一个名为 isHighPriority的简单任务方法,以演示方法如何在此设置下工作。

ListSchema定义中,您会注意到如何配置task键以容纳 TaskSchema对象的数组。任务密钥将成为 DocumentArray的实例,该实例提供了用于处理嵌入式Mongo文档的特殊方法。

现在,我只将 ListSchema对象传递到mongoose.model中,而省略TaskSchema。从技术上讲,不必将 TaskSchema转换为正式模型,因为我们不会将其保存在自己的收藏夹中。稍后,我将向您展示它对您没有任何危害,并且可以帮助您以相同的方式组织所有模型,尤其是当它们开始跨越多个文件时。

通过 List模型设置,我们可以向其中添加一些任务并将其保存到Mongo。

var List = mongoose.model('List');
var sampleList = new List({name:'Sample List'});

sampleList.tasks.push(
{name:'task one', priority:1},
{name:'task two', priority:5}
);

sampleList.save(function(err) {
if (err) {
console.log('error adding new list');
console.log(err);
} else {
console.log('new list successfully saved');
}
});


List模型( simpleList)实例上的task属性的工作方式类似于常规JavaScript数组,我们可以使用push向其添加新任务。需要注意的重要一点是,任务是作为常规JavaScript对象添加的。这是一个细微的区别,可能并不立即直观。

您可以从Mongo Shell验证新列表和任务是否已保存到mongo。

db.lists.find()
{ "tasks" : [
{
"_id" : ObjectId("4dd1cbeed77909f507000002"),
"priority" : 1,
"name" : "task one"
},
{
"_id" : ObjectId("4dd1cbeed77909f507000003"),
"priority" : 5,
"name" : "task two"
}
], "_id" : ObjectId("4dd1cbeed77909f507000001"), "name" : "Sample List" }


现在我们可以使用 ObjectId拉起 Sample List并遍历其任务。

List.findById('4dd1cbeed77909f507000001', function(err, list) {
console.log(list.name + ' retrieved');
list.tasks.forEach(function(task, index, array) {
console.log(task.name);
console.log(task.nameandpriority);
console.log(task.isHighPriority());
});
});


如果您运行最后的代码,则会收到一条错误消息,提示嵌入式文档没有方法 isHighPriority。在当前版本的Mongoose中,您无法直接访问嵌入式架构上的方法。有一个 open ticket可以解决,将问题提交给Mongoose Google小组后,manimal45发布了一个有用的解决方法,目前可以使用。

List.findById('4dd1cbeed77909f507000001', function(err, list) {
console.log(list.name + ' retrieved');
list.tasks.forEach(function(task, index, array) {
console.log(task.name);
console.log(task.nameandpriority);
console.log(task._schema.methods.isHighPriority.apply(task));
});
});


如果运行该代码,则应该在命令行上看到以下输出。

Sample List retrieved
task one
task one (1)
true
task two
task two (5)
false


考虑到这种解决方法,让我们将 TaskSchema变成猫鼬模型。

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');


TaskSchema定义与以前相同,因此我省略了。将其转换为模型后,我们仍然可以使用点表示法访问其基础的Schema对象。

让我们创建一个新列表并将两个Task模型实例嵌入其中。

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');
}
});


当我们将Task模型实例嵌入到列表中时,我们在它们上调用 toObject将其数据转换为 List.tasks DocumentArray期望的普通JavaScript对象。当您以这种方式保存模型实例时,嵌入的文档将包含 ObjectIds

完整的代码示例为 available as a gist。希望随着猫鼬的不断发展,这些变通办法可以使事情顺利进行。我对Mongoose和MongoDB还是很陌生,因此请随时在评论中分享更好的解决方案和技巧。快乐的数据建模!

关于mongodb - 为什么 Mongoose 同时具有模式和模型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44686721/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com