Mongoose:递归迭代以更新树状结构中的属性

时间:2018-03-20 18:35:53

标签: javascript node.js mongodb mongoose mongoose-schema

我有一个“树状”结构,我已经实现了存储注释。基本上每个“注释”都是一个节点,其中包含链接到另一个“注释”节点的“父”属性。我还在每个节点上存储一个“replyCount”字段,该字段跟踪链接到节点的节点数量,作为对特定“注释”节点的“回复”。

为了在将新注释添加到数据库后更新回复计数,我这样做。

    var done = false;
    while (!done) {
        console.log('Parent: ', parent);            
        Comments.findByIdAndUpdate(
                    parent,
                    {
                        $inc: {
                                replyCount: 1
                        }
                    },
                    (err, res) => {
                        if (err) done = true;       
                        console.log(res);
                        parent = res.parent;
                    });
    }

我这样做的逻辑是我找到当前节点的父节点(让我们称之为ParentNode),更新它的计数,将ParentNode的父节点设置为新父节点并继续直到我遇到错误(这将发生在根节点到达树),在这种情况下,我将“done”变量设置为true并退出while循环。

然而,由于在下一个while循环迭代之前没有调用回调函数,这个实现会一直陷入无限循环。

我想到的另一个策略是填充我需要更新计数的“父ID”列表。为了做到这一点,我仍然需要遍历我的树结构来获取我需要的id的列表。有没有更简单的方法来使用mongoose迭代结构?

编辑 - 这是我想要完成的内容的直观表示。

Comment Tree structure

当一个新的注释对象插入到db中时,我想相应地增加replyCount值。

1 个答案:

答案 0 :(得分:0)

由于对MongoDB的调用的异步性,while循环会给你带来很多麻烦。但是,设置一个递归函数,看看这是否更好。如果您开始使用几层深度的树,则可能会遇到速度问题,但这样您就不会再次调用该函数,直到完成第一个函数。

function updateParent(parent) {
    // stop the recursion once the parent is root
    if (parent === 'root') return
    Comments.findByIdAndUpdate(
                parent,
                {
                    $inc: {
                            replyCount: 1
                    }
                },
                (err, res) => {
                    if (err) return;       
                    console.log(res);
                    // call the function recursively with the new parent
                    updateParent(res.parent);
                });
}

您还可以查看aggregate函数是否可以帮助您计算回复计数,因为您已经链接了数据。