Use pipeline documents as graphlookup source

Hi Im trying to create a customisable graph structure. This is: we have a default graph with documents having a reference to their parents - like in the example from mongo docs:
https://docs.mongodb.com/manual/tutorial/model-tree-structures-with-parent-references/ - and have an array to customize the parent.

Lets get this example:

    /* 1 */
    {
        "_id" : "MongoDB",
        "parent" : "Databases",
        "poolDeltas" : []
    }

    /* 2 */
    {
        "_id" : "dbm",
        "parent" : "Databases",
        "poolDeltas" : [ 
            {
                "id" : "SomeId",
                "action" : "change-metadata",
                "metadata" : {
                    "parent" : "Languages"
                }
            }
        ]
    }

    /* 3 */
    {
        "_id" : "Databases",
        "parent" : "Programming",
        "poolDeltas" : []
    }

    /* 4 */
    {
        "_id" : "Languages",
        "parent" : "Programming",
        "poolDeltas" : [ 
            {
                "id" : "SomeId",
                "action" : "change-metadata",
                "metadata" : {
                    "parent" : "Movies"
                }
            }
        ]
    }

    /* 5 */
    {
        "_id" : "Programming",
        "parent" : "Books",
        "poolDeltas" : []
    }

    /* 6 */
    {
        "_id" : "Books",
        "parent" : null,
        "poolDeltas" : []
    }

    /* 7 */
    {
        "_id" : "Movies",
        "parent" : null
    }

The basic idea is to have delta to change the default values of the document. in This case is a delta to change the parent property.
After applying some mongo transformation with the aggregation pipeline we have the following results:

/* 1 */
{
    "_id" : "MongoDB",
    "parent" : "Databases",
    "orginalParent" : "Databases"
}

/* 2 */
{
    "_id" : "dbm",
    "parent" : "Languages",
    "orginalParent" : "Databases"
}

/* 3 */
{
    "_id" : "Databases",
    "parent" : "Programming",
    "orginalParent" : "Programming"
}

/* 4 */
{
    "_id" : "Languages",
    "parent" : "Movies",
    "orginalParent" : "Programming"
}

/* 5 */
{
    "_id" : "Programming",
    "parent" : "Books",
    "orginalParent" : "Books"
}

/* 6 */
{
    "_id" : "Books",
    "parent" : null,
    "orginalParent" : null
}

/* 7 */
{
    "_id" : "Movies",
    "parent" : null,
    "orginalParent" : null
}

The steps are:

db.topics.aggregate([
  {
    $project: {
      _id: true,
      parent: true,
      poolMetaData: {
        $reduce: {
          input: {
            $filter: {
              input: "$poolDeltas",
              as: "delta",
              cond: {
                $and: [
                  { $eq: ['$delta.id', 'SomeId'] },
                  { $eq: ['$delta.action', 'change-metadata'] },
                ]
              }
            }
          },
          initialValue: {},
          in: { $mergeObjects: ["$value", "$this.metadata"] }
        }
      }
    }
  },
  { $replaceRoot: { newRoot: { 
    $mergeObjects: [ 
      { _id: "$_id", parent: "$parent", orginalParent: "$parent" }, 
      "$poolMetaData" 
    ] 
  } } }
])

Now I want to perform a graph look to build the hierarchy after applying the deltas to the documents.

if i add this to the pipeline

{
    $graphLookup: {
      from: "topics",
      startWith: "$parent",
      connectFromField: "parent",
      connectToField: "_id",
      as: "topicsHierarchy"
    }
  }

I get the hierarchy almost right. It can get the parent of the node applying the deltas… but the hierarchy is wrong if there is some delta applied to parent-parent node. Its going to the default path and not get the delta for the parent-parent node. It gets the values from the collection and not from the “virtual collection” on the pipeline. How can i do it? Apply first all deltas for the context and then to the lookup? Did i make myself clear?

Thx

1 Like