简体   繁体   中英

Mongoose: Recursively iterate to update property in tree-like structure

I have a "tree-like" structure that I have implemented for storing comments. Basically every "comment" is a node which contains a "parent" property that links to another "comment" node. I am also storing a "replyCount" field on each node which tracks the number of nodes that are linked to the node as "replies" to the specific "comment" node.

In order to update the reply counts after a new comment is added to the database, I am doing this.

    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;
                    });
    }

My logic behind doing that is that I find the current node's parent (let's call it ParentNode), update its count, set that ParentNode's parent as the new parent and continue till I hit an error (which would happen when the root of tree is reached), in which case I set the "done" variable to true and exit out of the while loop.

However, this implementation keeps getting stuck in an infinite loop as the callback function doesn't get called before the next while loop iteration.

Another strategy that I have in mind is that I populate a list of "parent id's" that I need to update the count for. In order to do that I still need to traverse my tree structure to get a list of the id's I need. Is there a simpler way to iterate through the structure using mongoose?

Edit - Here is a visual representation of what I am trying to accomplish.

注释树结构

When a new comment object is inserted into the db, I would like to increment the replyCount values correspondingly.

The while loop will give you lots of trouble due to the asynchronous nature of the call to MongoDB. However, set up a recursive function and see if this works better. If you starting having trees that get several levels deep you may run into speed issues, but this way you won't call the function again until the first one had completed.

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);
                });
}

You may also look into whether or not aggregate functions could help you calculate the reply count, since you already have the data linked.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM