5

I have quite a large dataset where every Item has a hierarchy field with a children attribute which is an array of references to other Items. I want to get all top parent Items and populate the children all the way to the leafs.

Item = new Schema({
  ...,
  hierarchy: {
    children: [{
      type: mongoose.Schema,
      ref: 'Item'
    }],
  ...
})

Populate only fills one level and doesn't continue on down the tree. I have also tried mongoose-deep-populate but couldn't get it to work. Could I write a recursive function to make it populate all fields? One idea I had was to write it something like this:

items = _.map(items, function(item){
  return populateChildren(item);
});

function populateChildren(item){
    if(item.hierarchy && item.hierarchy.children && item.hierarchy.children.length > 0){
        item.hierarchy.children = _.map(item.hierarchy.children, function(child){
            console.log(count++, child);
            return Item.findById(child).exec(function(err, child){
                return populateChildren(child);
            })
        });
    }
    return item;
}

Any ideas on how I could populate the hierarchy?

trevligheten
  • 306
  • 2
  • 13
  • 1
    The issue with recursion when populating in this way is that unless the child document somehow has knowledge of all of the other documents in the tree you could end up with an infinite loop. If a child 4 nodes down has a reference to the first item it will never end. You should have one function to populate all children and keep track of the _ids of every populated doc and skip those that have already been populated. The easiest way is to have a "top level _id" property, so you can grab them all and just process them all on the client side without having to do db calls for each record. – Brian Shamblen Jun 30 '15 at 14:39

0 Answers0