像这样的问题还有很多,但不幸的是我没有发现任何一个适合我的情况。
最接近的是 Create a JSON tree in Node.Js from MongoDB但它仍然没有按预期工作。
或者也许我的头脑无法解决这个问题......
我的架构表明我的问题的关键组件如下所示:
var userSchema = new Schema({
_id: {type: Number},
children: [{type: Number, ref: 'User'}]
)};
每个用户可能有三个子用户,因此它可以无限深入。
幸运的是,我必须涵盖两种情况 -
- 从特定用户构建最多 3 个嵌套的 json 树
- 计算来自特定根的 10 个嵌套的数据。
我尝试在我的express.js api中编写这样的递归函数:
api.get('/user/tree/:user_id', function (req, res) {
var user_id = req.params.user_id;
var depth = 0;
var root = {};
function walker(parent) {
if (depth >= 3) {
return res.send('whole data, not just last user'); // this is wrong. it will try to res.send for each iteration of forEach, and it sends only last user.
}
depth += 1;
_.forEach(parent.mlm.childs, function (userid, index) {
User.findOneAsync({_id: userid}).then(function(user) {
parent.mlm.childs[index] = user;
walker(parent.mlm.childs[index]);
});
});
}
User.findOneAsync({_id: user_id}).then(function(user) {
root = user;
walker(user, root);
});
});
但当然它只遍历树,而不是遍历并创建整个 JSON。
我不知道如何访问根并发送整个树。
我猜,发送大量 res.send 的问题可以通过计算迭代次数来解决,并且仅在 forEach 结束时才发送。
感谢您的帮助。
最佳答案
好的。我找到了解决方案。
api.get('/user/tree/:user_id', function (req, res) {
var user_id = req.params.user_id;
var tree = {};
var counter = 0;
var gloCounter = 0;
function walker(parent) {
gloCounter += 1;
if (parent.mlm.childs.length === 0 && gloCounter > counter) {
res.send(tree);
return;
}
_.forEach(parent.mlm.childs, function (child, i) {
counter += 1;
User.findOneAsync({_id: child})
.then(function(child) {
parent.mlm.childs[i] = child;
var newParent = parent.mlm.childs[i];
walker(newParent);
}).catch(function(err) {
console.log('error: ' + err);
});
});
}
User.findOneAsync({_id: user_id})
.then(function(user) {
tree = user;
walker(tree);
}).catch(function(err) {
console.log('err: ' + err);
});
});
它按预期工作 - 遍历整个结构,并创建 json,然后发送回来。 它使用 lodash 和 bluebird promise ,为那些将来解决类似问题并且不了解所有这些“异步”后缀和 _.forEach 发生了什么的人提供帮助。
关于node.js - 从node.js中的mongoDB数据生成JSON树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25238199/