我不能手动或自动填充新保存的对象上的创建者字段...我能找到的唯一方法是重新查询我已经拥有的我不想做的对象 .
这是设置:
var userSchema = new mongoose.Schema({
name: String,
});
var User = db.model('User', userSchema);
var bookSchema = new mongoose.Schema({
_creator: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
description: String,
});
var Book = db.model('Book', bookSchema);
这是我拉我的头发的地方
var user = new User();
user.save(function(err) {
var book = new Book({
_creator: user,
});
book.save(function(err){
console.log(book._creator); // is just an object id
book._creator = user; // still only attaches the object id due to Mongoose magic
console.log(book._creator); // Again: is just an object id
// I really want book._creator to be a user without having to go back to the db ... any suggestions?
});
});
编辑:最新的mongoose解决了这个问题并添加了填充功能,请参阅新接受的答案 .
10 回答
您应该能够使用Model的populate函数来执行此操作:http://mongoosejs.com/docs/api.html#model_Model.populate在book的保存处理程序中,而不是:
你会做类似的事情:
可能来得太晚了,无法帮助你,但最近我被困在这个问题上,对其他人来说可能有用 .
如果有人还在寻找这个 .
Mongoose 3.6引入了许多很酷的功能来填充:
要么:
更多信息见:https://github.com/LearnBoost/mongoose/wiki/3.6-Release-Notes#population
但是这样你仍然会再次查询用户 .
在没有额外查询的情况下完成它的一个小技巧是:
只是为了详细说明并给出另一个例子,因为它帮助了我 . 这可能有助于那些想要在保存后检索部分填充对象的人 . 该方法也略有不同 . 花了一两个多小时寻找正确的方法 .
返回promise的解决方案(无回调):
Use Document#populate
Possible Implementation
阅读有关文档填充here的信息 .
我的解决方案是使用
execPopulate
,就像这样我想我会加上这个来澄清像我这样的完整新手的东西 .
如果你不小心,有什么令人困惑的是,有三种截然不同的填充方法 . 它们是不同对象的方法(模型与文档),采用不同的输入并给出不同的输出(Document vs. Promise) .
在这里,他们是那些困惑的人:
Document.prototype.populate()
See full docs.
这个适用于文档并返回文档 . 在原始示例中,它看起来像这样:
因为它适用于文档并返回文档,所以您可以将它们链接在一起,如下所示:
但是,不要像我一样愚蠢,并尝试这样做:
请记住:Document.prototype.populate()返回一个文档,所以这是无稽之谈 . 如果你想要一个承诺,你需要......
Document.prototype.execPopulate()
See full docs.
这个适用于文档,但它返回一个解析为文档的promise . 换句话说,您可以像这样使用它:
那更好 . 最后,还有......
Model.populate()
See full docs.
这个 works on models 并返回一个承诺 . 因此使用方式略有不同:
希望这能帮助其他一些新人 .
不幸的是,这是一个长期存在的猫鼬问题,我认为还没有解决:
https://github.com/LearnBoost/mongoose/issues/570
您可以做的是为此编写自己的自定义getter / setter(并在单独的属性中设置实际
_customer
) . 例如:NOTE: 我没有测试它,它可能与
.populate
奇怪地工作并且设置纯粹的id .猫鼬5.2.7
这对我有用(只是很头疼!)
可能是某事 . 喜欢
将这项工作作为最好和最不成问题的方法(使用Bluebird承诺) .
最后写了一些curry-able Promise函数,你可以在其中声明你的schema,query_adapter,data_adapter函数并提前填充字符串 . 更简单/更简单的实现更容易 .
它可能不是超级高效,但我认为执行位非常优雅 .
github文件:curry_Promises.js
declartion
execution