title: Recursively populate parent-child tree from MongoDB collection
body: <p>I have a MongoDB database with a collection, using a mixture of Parent and Child References.</p>
  <p>Each document in the collection includes two properties: <code>parentId</code> and <code>childIds</code>.</p>
  <p>The <code>parentId</code> property is an (<code>ObjectId</code>) reference to the parent document.</p>
  <p>The <code>childIds</code> property is an array of (<code>ObjectId</code>) references to child documents.</p>
  <p>Given the collection:</p>
  <pre class="lang-json prettyprint-override"><code>[
    {
      &quot;_id&quot;: {
        &quot;$oid&quot;: &quot;625fa5b1a8142aef1a1d034d&quot;
      },
      &quot;taskId&quot;: 1,
      &quot;taskName&quot;: &quot;New Task 1&quot;,
      &quot;parentId&quot;: null,
      &quot;childIds&quot;: [
        {
          &quot;$oid&quot;: &quot;625fa66a409d15316aada92e&quot;
        }
      ],
      &quot;subtasks&quot;: []
    },
    {
      &quot;_id&quot;: {
        &quot;$oid&quot;: &quot;625fa66a409d15316aada92e&quot;
      },
      &quot;taskId&quot;: 2,
      &quot;taskName&quot;: &quot;New Task 2&quot;,
      &quot;parentId&quot;: {
        &quot;$oid&quot;: &quot;625fa5b1a8142aef1a1d034d&quot;
      },
      &quot;childIds&quot;: [
        {
          &quot;$oid&quot;: &quot;625fc16c409d15316aada94c&quot;
        }
      ],
      &quot;subtasks&quot;: []
    },
    {
      &quot;_id&quot;: {
        &quot;$oid&quot;: &quot;625fc16c409d15316aada94c&quot;
      },
      &quot;taskId&quot;: 3,
      &quot;taskName&quot;: &quot;New Task 3&quot;,
      &quot;parentId&quot;: {
        &quot;$oid&quot;: &quot;625fa66a409d15316aada92e&quot;
      },
      &quot;childIds&quot;: [],
      &quot;subtasks&quot;: []
    },
    {
      &quot;_id&quot;: {
        &quot;$oid&quot;: &quot;625fc16f409d15316aada94f&quot;
      },
      &quot;taskId&quot;: 4,
      &quot;taskName&quot;: &quot;New Task 4&quot;,
      &quot;parentId&quot;: null,
      &quot;childIds&quot;: [
        {
          &quot;$oid&quot;: &quot;625fc173409d15316aada952&quot;
        }
      ],
      &quot;subtasks&quot;: []
    },
    {
      &quot;_id&quot;: {
        &quot;$oid&quot;: &quot;625fc173409d15316aada952&quot;
      },
      &quot;taskId&quot;: 5,
      &quot;taskName&quot;: &quot;New Task 5&quot;,
      &quot;parentId&quot;: {
        &quot;$oid&quot;: &quot;625fc16f409d15316aada94f&quot;
      },
      &quot;childIds&quot;: [],
      &quot;subtasks&quot;: []
    }
  ]
  </code></pre>
  <p>My goal is to populate a recursive tree structure from that collection that can be sent to the client, so any child object will be in it's respective parent <code>subtasks</code> array like:</p>
  <pre class="lang-json prettyprint-override"><code>[
    {
      &quot;_id&quot;: &quot;625fa5b1a8142aef1a1d034d&quot;,
      &quot;taskId&quot;: 1,
      &quot;taskName&quot;: &quot;New Task 1&quot;,
      // This is a parent task so parentId is null
      &quot;parentId&quot;: null,
      &quot;childIds&quot;: [&quot;625fa66a409d15316aada92e&quot;],
      // subtasks will be the objects of the childIds,
      // just 625fa66a409d15316aada92e in this case
      &quot;subtasks&quot;: [
        {
          &quot;_id&quot;: &quot;625fa66a409d15316aada92e&quot;,
          &quot;taskId&quot;: 2,
          &quot;taskName&quot;: &quot;New Task 2&quot;,
          // This is a child, but also has children,
          // so both parentId and childIds are present
          &quot;parentId&quot;: &quot;625fa5b1a8142aef1a1d034d&quot;,
          &quot;childIds&quot;: [&quot;625fc16c409d15316aada94c&quot;],
          &quot;subtasks&quot;: [
            {
              &quot;_id&quot;: &quot;625fc16c409d15316aada94c&quot;,
              &quot;taskId&quot;: 3,
              &quot;taskName&quot;: &quot;New Task 3&quot;,
              &quot;parentId&quot;: &quot;625fa66a409d15316aada92e&quot;,
              &quot;childIds&quot;: [],
              &quot;subtasks&quot;: []
            }
          ]
        }
        // ... More subtasks
      ]
    },
    {
      &quot;_id&quot;: &quot;625fc16f409d15316aada94f&quot;,
      &quot;taskId&quot;: 4,
      &quot;taskName&quot;: &quot;New Task 4&quot;,
      &quot;parentId&quot;: null,
      &quot;childIds&quot;: [&quot;625fc173409d15316aada952&quot;],
      &quot;subtasks&quot;: [
        {
          &quot;_id&quot;: &quot;625fc173409d15316aada952&quot;,
          &quot;taskId&quot;: 5,
          &quot;taskName&quot;: &quot;New Task 5&quot;,
          &quot;parentId&quot;: &quot;625fc16f409d15316aada94f&quot;,
          &quot;childIds&quot;: [],
          &quot;subtasks&quot;: []
        }
      ]
    }
    // ... More tasks
  ]
  </code></pre>
  <p>I'm looking through similar issues that suggest using <code>populate</code> or <code>aggregate</code> but don't have anything concrete to start with.</p>
  <p>I currently just have this, where <code>result</code> is the array of documents from the collection <em>as is</em>:</p>
  <pre class="lang-js prettyprint-override"><code>export class Task extends Service {
    constructor(options: Partial&lt;MongooseServiceOptions&gt;, app: Application) {
      super(options);
    }
  
    find(params: Params): any {
      return super.find(params).then((result: any) =&gt; {
        // Todo: Populate parent-child tree structure to send to client
  
        return result;
      });
    }
  }
  </code></pre>