Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript mongoDB中的迭代树_Javascript_Node.js_Mongodb_Tree - Fatal编程技术网

Javascript mongoDB中的迭代树

Javascript mongoDB中的迭代树,javascript,node.js,mongodb,tree,Javascript,Node.js,Mongodb,Tree,我收集了如下数据(例如): 我正在尝试编写一个函数来接收\u id,并返回此节点任何深度的所有子节点,例如\u id=0,我需要如下内容: [ { name : "Richard" , parent_id : "0" , depth : "1" , _id : "1" }, { name : "Kevin" , parent_id : "0" , depth :

我收集了如下数据(例如):

我正在尝试编写一个函数来接收
\u id
,并返回此节点任何深度的所有子节点,例如
\u 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实现这一点?
任何想法都是有用的,谢谢。

为了实现目标,你可以使用两种著名的算法
和。
对于这个问题,BFS优于DFS,因为您可以在O(logn)中跟踪您的树 您也可以使用DFS,但您必须以递归方式实现它,并且运行时间将为O(n),因为您在节点js中编码,所以您必须以异步方式实现它,实现起来可能有点困难。
为了实现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) });
    });
}

注意:我还保存了每个查询的深度,这样您就可以获得每个查询的深度,并知道该查询在树中的位置。

如果您不想编写自己的逻辑,那么有一个模块可以查询JSON对象:。这个模块是什么?如:JSON查询和变异库。它以post顺序(先叶,后根)遍历对象和数组中的树结构,返回与查询中传递的部分结构匹配的节点,并允许您更改或替换匹配的节点。除了下面的答案,您可能还需要考虑更改文档设计以更好地支持查询。请看一下MongoDB手册中的建议。我使用家长参考:除了MongoDB文档之外,您还有更好的想法吗?
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) });
    });
}