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