微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

javascript – 在mongoDB中迭代树

我有这样的数据集合(例如):

{
    name : "john" ,
    _id : "0"
},
{
    name : "Richard" ,
    parent_id : "0" ,
    _id : "1"
},
{
    name : "Kevin" ,
    parent_id : "0" ,
    _id : "2"
},
{
    name : "William" ,
    parent_id : "1" ,
    _id : "3"
},
{
    name : "George" ,
    parent_id : "3" ,
    _id : "4"
}

我正在尝试编写一个函数来接收_id并返回此节点任何深度的所有子节点,例如_id = 0我需要这样的东西:

[
    {
        name : "Richard" ,
        parent_id : "0" ,
        depth : "1" ,
        _id : "1"
    },
    {
        name : "Kevin" ,
        parent_id : "0" ,
        depth : "1" ,
        _id : "2"
    },
    {
        name : "William" ,
        parent_id : "1" ,
        depth : "2" ,
        _id : "3"
    },
    {
        name : "George" ,
        parent_id : "3" ,
        depth : "3" ,
        _id : "4"
    }
]

我写了几个递归函数来迭代我的mongodb文档但主要问题是我无法处理回调(异步)并且不知道何时以及如何结束递归函数.

我怎么能用mongodb和node.js做到这一点?
任何想法都有用,谢谢.

解决方法:

您可以使用2种着名算法来实现目标
 BFS(Breath First search)DFS(Depth First Search).
对于这个问题,BFS优于DFS,因为您可以在O(logn)中跟踪树
您也可以使用DFS但是必须以递归方式实现它,并且运行时间将是O(n)并且因为您在节点j中编码,所以必须在异步中实现它并且实现它可能有点困难.
为了实现BFS算法,你必须使用异步while循环,因为你必须在你的while循环中使用mongo查询,如果你使用普通的javascript你的BFS将无法工作,因为我们讨论的是节点js而不是PHP !!!
所以首先这是我在BFS代码中使用的异步while循环

function asyncLoop(iterations, func, callback ,foo) {
        var done = false;
        var loop = {
            next: function() {
                if (done) {
                    return;
                }

                if (iterations) {
                    func(loop);

                } else {
                    done = true;
                    if(callback) callback(foo);
                }
            },

            isEnd : function(){
                return done ;
            } ,

            refresh : function(it){
                iterations = it ;
            },

            break: function() {
                done = true;
                callback();
            }
        };
        loop.next();
        return loop;
    }

这是BFS算法节点js代码

function bfs (_id ,callback){
    _id = String(_id);
    var q = [] ,res = [] ;

    db.tasks.findOne({ _id : _id }).lean().exec(function(err,root){
        root.depth = 0 ;
        q.push(root);

        asyncLoop(q.length ,function(loop){
            res.push(q[0]);
            db.tasks.find({ _parent : q[0]._id }).lean().exec(function(err,new_nodes){
                if(err) console.log(err);
                else {
                    var d = q[0].depth ;
                    q.shift();
                    loop.refresh(new_nodes.length + q.length);
                    if(new_nodes.length > 0){
                        new_nodes.forEach(function(new_node){
                            new_node.depth = d+1 ;
                            q.push(new_node);
                        });
                    }
                    loop.next();
                }
            });

        },function(){ callback(res) });
    });
}

注意:我还保存每个查询的深度,以便您可以获得每个查询的深度并知道此查询在树中的位置.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐