我正在尝试填充我的模型,如下所示:
var Org = new mongoose.Schema({
_id: {type: String, unique:true}, //this will be the org code
name: String,
level: String,
children: [{type: String, ref: 'Org'}]
});
//Orgs have children orgs, which themselves can have children orgs at N levels
鉴于一个组织,我想填充其子女及其子女等。我可以为N = 2级别完成此任务:
req.Model.findOne({_id: id}).populate('children').exec(function(err, doc){
if (err){
return next(err);
}
req.Model.populate(doc, {path: 'children.children'}, function(err, doc){
if(err){
return next(err);
}
return res.json(doc);
});
});
现在几个小时我一直试图用承诺完成上述工作,即使在N = 2时也是如此。我认为对于N = *级别,使用mongoose具有内置实现的promise这样做会更干净。
req.Model.findOne({_id: id}).populate('children').exec()
.then(function (doc){
if(!treeView) {
return doc;
}
return req.Model.populate(doc, {path: 'children.children'});
})
.then(function (doc){
return res.json(doc);
},function(err){
return next(err);
});
// treeView is a query string that lets me know that I need to populate the refs
我认为它的工作原理如下:
我收到此错误:
{
"status": "error",
"serverTimestamp": "2014-07-24T18:23:02.974Z",
"message": "\"function\" == \"undefined\""
}
我知道它会到达第二个then()的错误处理程序,因为我已经注销到控制台进行验证,但我无法弄清楚为什么会发生这种情况。一旦我能够使这个工作,我将尝试使其适用于N = *级别,我想这将涉及递归地创建更多的承诺。我在这里看到很多相关的问题,但不完全是我需要的。
非常感谢任何帮助。
答案 0 :(得分:2)
我能够使用从mongoose模型返回的Mongoose承诺,使MongooseJS v4.1中的嵌套子文档填充工作。无需使用其他承诺库。
var fuelOrderId = req.params.fuelOrderId;
fuelOrderModel.findById(fuelOrderId).populate('aircraftId')
.then(function(order){
return fuelOrderModel.populate(order,
{path: 'aircraftId.aircraftContacts',
model: 'aircraftContactModel'});
})
.then(function(result){
res.json({
fuelOrder: result,
status: 1
});
},function(err){
console.error(err);
res.json({err: err, status: 0});
})
修改考虑使用.catch()
代替第二个函数进行错误。 mpromise现在支持.catch()
。
答案 1 :(得分:1)
现在似乎找到了一个解决方案。
Q.ninvoke(doc, 'populate',{path: children.children})
.then(function(doc){
return res.json(doc);
},function(err) {
return next(err);
});
对我来说奇怪的是我需要使用mongooses Document.populate而不是Model.populate(doc ..),根据文档,它应该表现得非常相似,除了返回一个promise。这是我必须使用Q promise api的一个原因,因为Document.populate不会像Model.populate那样返回一个承诺。我无法让Model.populate在没有常规节点样式回调的情况下工作,但是这个解决方案可以满足我的需求。至于N = *级别,我只是根据需要递归调用Q.ninvoke多次,扩展路径,我可以根据需要填充多个级别。