node.js - 从node.js中的mongoDB数据生成JSON树

标签 node.js mongodb express tree mongoose

像这样的问题还有很多,但不幸的是我没有发现任何一个适合我的情况。

最接近的是 Create a JSON tree in Node.Js from MongoDB但它仍然没有按预期工作。

或者也许我的头脑无法解决这个问题......

我的架构表明我的问题的关键组件如下所示:

var userSchema = new Schema({
    _id:            {type: Number},
    children:   [{type: Number, ref: 'User'}]
)};

每个用户可能有三个子用户,因此它可以无限深入。

幸运的是,我必须涵盖两种情况 -

  1. 从特定用户构建最多 3 个嵌套的 json 树
  2. 计算来自特定根的 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/

相关文章:

node.js - Express:从另一个中间件调用一个中间件

javascript - 在字符串化为 JSON 之前修改实体

javascript - 在 JavaScript 中从 Firebase 中删除特定 Node

javascript - 当我的查询结果 rowCount 为 0 时,如何检查 Node js 中的响应抛出错误

java - 我们如何通过 java 驱动程序查询嵌入式文档?

node.js - 像 Angular 部分一样渲染 Jade

node.js - 无法使用 NPM 安装 Webpack

node.js - 在 Express 路由器中使用 mongoDB

php - Mongodb "Remote server has closed the connection"重启后第一次连接

node.js - socket.request.user 在 Passport.js、Socket.io 和 Express 中未定义