I built up a graph structure using MongoDB. I did some complex queries on this structure already, but I am struggling on selecting a subgraph of a given depth starting from a specific node via the aggregation pipeline.
I already did use the $graphLookup to get all the required nodes, which gives the following result:
{ "_id" : "O_4", "name" : "D", "type" : "Info", "links" : [ { "link" : "L_2", "objectId" : "O_1" }, { "link" : "L_4", "objectId" : "O_3" }, { "link" : "L_10", "objectId" : "O_6" } ] }
{ "_id" : "O_2", "name" : "B", "type" : "Info", "links" : [ { "link" : "L_1", "objectId" : "O_1" }, { "link" : "L_3", "objectId" : "O_3" } ] }
{ "_id" : "O_1", "name" : "A", "type" : "Info", "links" : [ { "link" : "L_1", "objectId" : "O_2" }, { "link" : "L_2", "objectId" : "O_4" } ] }
{ "_id" : "O_3", "name" : "C", "type" : "Info", "links" : [ { "link" : "L_3", "objectId" : "O_2" }, { "link" : "L_4", "objectId" : "O_4" }, { "link" : "L_5", "objectId" : "O_5" }, { "link" : "L_6", "objectId" : "O_7" } ] }
{ "_id" : "O_6", "name" : "F", "type" : "System", "links" : [ { "link" : "L_8", "objectId" : "O_7" }, { "link" : "L_9", "objectId" : "O_5" }, { "link" : "L_10", "objectId" : "O_4" } ] }
But now I want to remove the nested "link" objects (in array "links") where the "objectId" is not present in the above result, i.e. in "O_6" the link "L_8" should be removed, since the node "O_7" is not part of the subgraph.
I already tried playing around with $in, $facet and other stuff to get this problem solved, but it seems like I am unable ...
Maybe, you guys can help out?
Edit:
Just found a solution more or less - $filter
does a decent job here:
{
$unwind: "$links"
}, {
$group: {
_id: null,
ids: {
$addToSet: "$_id"
},
links: {
$addToSet: "$links"
}
}
}, {
$project: {
links: {
$filter: {
input: "$links",
as: "link",
cond: {
$in: ["$$link.objectId", "$ids"]
}
}
}
}
}, {
$unwind: "$links"
}, {
$replaceRoot: {
newRoot: "$links"
}
}, {
$group: {
_id: "$link"
}
}
Returns what I needed - the list of Link-IDs:
{ "_id" : "L_1" }
{ "_id" : "L_10" }
{ "_id" : "L_3" }
{ "_id" : "L_2" }
{ "_id" : "L_4" }