像mongoose文件的结构一样在树上recursion

我需要帮助从我的数据库通过get请求拉出对象的对象,所以我可以在我的网页上显示所有的对象,但是我运行的这个testing已经失败了,debugging它,它只是运行到永远,并且从不接收JSON。 我认为我的逻辑可能会被搞乱。 我不确定是否应该使用asynchronous,这看起来像callback地狱,现在想想我应该,但我不知道如果在优化思考如果这是一个体面的方式,我通常从最坏的情况下,我试图低于我的目标是围绕O(N),因为有N个文件,我只是遍历一个recursion树,还有一些额外的查询,以find最初的文件和什么不是这样,N + X(其中x是额外的查询量<N)。 但是我觉得我好像在思想上错过了一些东西,好像有更好的办法。

我有一个架构,像这样

Doc { title : string, author : string, subDoc : [{type: mongoose.Schema.Types.ObjectId, ref : 'Doc'}] } 

所以有我生成的文件,每次我生成这些文件我有这些文件可以存在的子文档,甚至这些子文档可以有子文档。 然后我们结束了一些树状结构。 但是我不想显示文档>然后它的sub_doc1>所有的子目录…等>其子文档2>所有的子文档..>等等。

不过,我不知道我在想什么是有效的,甚至是值得做这么多的查询。

 app.get('/docs/:doc/subDocTree', function(req, res) { var array = []; var id = req.params.doc; var num_proc = 0; console.log(id); Doc.findById(id, function(err, doc) { console.log(doc); for (var x = 0; x < doc.subDoc.length; x++) { Doc.findById(form.subDoc[x], function(err, subDoc) { populate(subDoc); }); } num_proc = num_proc + 1; if (num_proc == Doc.subDoc.length) { res.json(array); array.length = 0; } }); }); function populate(docs) { var num_proc = 0; Form.findById(docss, function(err, doc) { if (doc.subform.length != 0) { //console.log(form); var total = doc.subDoc.length; for (var i = 0; i < total; i++) { array.push(doc.subDoc[x]); num_proc = num_proc + 1; populate(subDoc[x]); } } }); } 

我认为首先search文档,然后search所有的子文档,然后recursion检查填充方法的任何subdocs subdocs将工作。 然而,我永远不会收到JSON,并通过打印语句/ console.logsdebugging,我仍然无法弄清楚我错了什么地方。

你的代码是asynchronous的,不适用于循环。

 for (var x = 0; x < doc.subDoc.length; x++) { Doc.findById(form.subDoc[x], function(err, subDoc) { populate(subDoc); }); } num_proc = num_proc + 1; if (num_proc == Doc.subDoc.length) { res.json(array); array.length = 0; } 

populate(subDoc) 之前执行res.json(array) populate(subDoc)

你应该使用asynchronous库或承诺来处理这个。

另外mongoose已经有一个内置的方法来填充子文件。


**** ****更新

看来你会从这个模块中受益: 深度填充

结合承诺,我将如何重写你的代码:

首先,我会提供mongoose对象(使用蓝鸟 )

 // Promisification var Promise = require('bluebird'); var mongoose = require('mongoose'); Promise.promisifyAll(mongoose); 

然后在架构定义中,我会使用这个深度插件

 var deepPopulate = require('mongoose-deep-populate'); Doc.plugin(deepPopulate, options); 

所以现在你的路线如下所示:

 app.get('/docs/:doc/subDocTree', function(req, res) { var id = req.params.doc; Doc.findById(id).deepPopulate('subDoc').execAsync() .then(function(doc){ res.json(doc.subDoc); }).catch(function(err){ // handle error res.send('Something went wrong...' + err.message); }); });