Mongoose 添加到对象以填充猫鼬模型中的种群
我是刚接触猫鼬的,而且我的脑袋也不熟悉猫鼬的种群。我的模式看起来像Mongoose 添加到对象以填充猫鼬模型中的种群,mongoose,mongoose-populate,Mongoose,Mongoose Populate,我是刚接触猫鼬的,而且我的脑袋也不熟悉猫鼬的种群。我的模式看起来像 var ProjectSchema = new Schema({ name: { type: String, default: '', required: 'Please fill Project name', trim: true }, created: { type: Date, default: Date
var ProjectSchema = new Schema({
name: {
type: String,
default: '',
required: 'Please fill Project name',
trim: true
},
created: {
type: Date,
default: Date.now
},
topics: [{
type: Schema.ObjectId,
ref: 'Topic'
}]
});
当我查询项目时,我使用.populate('topics'),它工作正常。填充项目时,“主题”属性将保存实际对象而不是引用
另外,该主题没有项目参考(我发现在MongoDB中很难维护resiprocal关系)
我的问题是:当我想向项目添加主题对象时。是否添加ObjectId或对象本身?如果主题架构具有项目引用,则只需保存ObjectId,因为将引用保存到其他文档的方式与通常保存属性的方式相同,只需指定_id值:
var topicSchema = Schema({
_author : { type: Schema.ObjectId, ref: 'Project' },
title : String
});
var Topic = mongoose.model('Topic', topicSchema);
var Project = mongoose.model('Project', projectSchema);
var my_project = new Project({ name: 'Test Project' });
my_project.save(function (err) {
if (err) return handleError(err);
var topic1 = new Topic({
title: "My Topic",
_author: my_project._id // assign the _id from the project
});
topic1.save(function (err) {
if (err) return handleError(err);
// thats it!
});
});
有关更多详细信息,请参阅
--编辑-- 如果主题架构没有项目引用,则需要推送对象本身:
var Topic = mongoose.model('Topic', topicSchema);
var Project = mongoose.model('Project', projectSchema);
var my_project = new Project({ name: 'Test Project' });
var topic1 = new Topic({
title: "My Topic"
});
my_project.stories.push(topic1);
my_project.save(callback);
我看到了这个问题和给出的答案,但我不认为它真的解释了你的问题,所以我认为这里有些东西是值得的 如所提供的模式所示,“topics”属性是一个“referenced array”,这基本上意味着它将保存对位于另一个集合中的文档的“reference”(或者本质上是一个
ObjectId
值)。mongoose的“模式”定义将其与对象所在的“关联”模型联系在一起,您应该知道
提出的问题是“我是推送对象,还是只推送\u id
值”,这本身就引发了一些关于“您在这里真正想做什么”的问题
最后,以下面的代码示例为例(假定模型和模式都已定义):
var project=newproject({“name”:“something”});
var topic=新主题({“name”:“something”});
project.topics.push(主题);//这实际上只是添加了_id,因为它是一个ref
//更多用于在其集合中保存主题和项目的代码
因此,根据代码中的注释,mongoose实际上只将“_id”值添加到父文档中,即使您要求它“推送”整个“对象”。它只是通过提供给模型的模式接口来解决“这就是您想要做的”。在代码中真正做到这一点并不难,但只是为了让您了解底层机制
您也可以从创建的对象中“使用\u id
值”(为了安全起见保存后),然后通过类似的方式将其添加到数组中。结果大致相同:
var project=newproject({“name”:“something”});
//是的,我们保存了项目对象,但后来。。。
var topic=新主题({“name”:“something”});
保存(函数(错误,主题){
if(err)throw(err)://或更好的处理
project.topics.push(topic.\u id);//显式
});
这种方法很好,当然前提是通过某种形式,在处理项目
和主题
时,您实际上拥有“内存中的对象”,以及适当的数据
另一方面,让我们假设Project
表示集合中的对象,尽管您知道它是\u id
值或其他表示属性的“唯一”值,但该对象数据实际上并未通过.findOne()
操作类型或类似操作从数据库加载
然后,让我们假设您没有驻留在内存中的项目
模型数据。那么如何添加新主题呢
这就是MongoDB的本机操作符发挥作用的地方。特别是,它当然类似于JavaScript中的.push()
数组操作符,但具有特定的“服务器端”操作
如前所述,您没有加载项目
模型数据,但希望通过将所需的主题
对象“推”到项目
对象集合中定义的某个对象(通过其标识符)来修改存储中的特定项目
项:
var-topic=新主题({“name”:“something”});
保存(函数(错误,主题){
if(err)抛出err;//或更好的处理
Project.update(
{u id:projectd},
{“$push”:{
“主题”:主题。\u id
}},
功能(错误,未受影响){
//并在这里处理响应
}
);
})
“更新”机制可以是.findOneAndUpdate()
或者甚至是.findbyiandupdate()
,只要您认为合适(这些方法都会在默认情况下将修改过的对象返回到.update()
不返回的位置),以实现您在此处操作的结果
与前面方法的主要区别在于,由于要修改的项目
的对象不驻留在应用程序代码的内存中,因此您可以使用这些方法在服务器上对其进行修改。这可能是一件“好事”,因为您不需要仅为了修改而“加载”该数据。MongoDB操作符允许您$push
数组内容,而无需先加载
这种方法实际上是在高事务处理系统中实现“并发更新”的最佳方法。原因是,在应用程序中的.findOne()
或类似操作与最终的.save()
操作的修改之间,“不能保证”在这些操作之间服务器存储上“没有数据被更改”
$push
操作符“确保”服务器上修改的数据在执行时保持“原样”,当然,添加到阵列中的新数据也是如此
这里的另一个显而易见的事情是,由于操作使用本地MongoDB操作符来实现这种效率,所以mongoose模式规则是以ByBased为基础的。所以你当然不能只是“p”