我正在尝试使用新的MongoDB v3.4 $ graphLookup聚合管道元素。我有数据“节点”,可以有0,1或多个父节点。每个节点还可以具有0,1或多个子节点。我想使用$ graphLookup来产生以下输出:
{"parentNodeKey": undefined, "parentLabel": undefined, "nodeKey": 1, "nodeLabel": "Node 1"},
{"parentNodeKey": 1, "parentLabel": "Node 1", "nodeKey": 11, "nodeLabel": "Node 1.1"},
{"parentNodeKey": 1, "parentLabel": "Node 1", "nodeKey": 12, "nodeLabel": "Node 1.2"},
{"parentNodeKey": 1, "parentLabel": "Node 1", "nodeKey": 13, "nodeLabel": "Node 1.3"},
{"parentNodeKey": 1, "parentLabel": "Node 1", "nodeKey": 31, "nodeLabel": "Node 3.1"},
{"parentNodeKey": 11, "parentLabel": "Node 1.1", "nodeKey": 111, "nodeLabel": "Node 1.1.1"},
{"parentNodeKey": 11, "parentLabel": "Node 1.1", "nodeKey": 112, "nodeLabel": "Node 1.1.2"},
{"parentNodeKey": 12, "parentLabel": "Node 1.2", "nodeKey": 121, "nodeLabel": "Node 1.2.1"},
{"parentNodeKey": 12, "parentLabel": "Node 1.2", "nodeKey": 122, "nodeLabel": "Node 1.2.2"}
数据存储在以下模式中(如有必要,我可以更改):
{"_id": 1, "nodeKey": 1, "label": "Node 1", "children": [{"nodeKey": 11, "label": "Node 1.1"}
,{"nodeKey": 12, "label": "Node 1.2"}
,{"nodeKey": 13, "label": "Node 1.3"}
,{"nodeKey": 31, "label": "Node 3.1"}
]},
{"_id": 2, "nodeKey": 2, "label": "Node 2", "children": [{"nodeKey": 21, "label": "Node 2.1"}
,{"nodeKey": 22, "label": "Node 2.2"}
,{"nodeKey": 23, "label": "Node 2.3"}
,{"nodeKey": 12, "label": "Node 1.2"}
,{"nodeKey": 31, "label": "Node 3.1"}
]},
{"_id": 3, "nodeKey": 3, "label": "Node 3", "children": [{"nodeKey": 31, "label": "Node 3.1"}
,{"nodeKey": 32, "label": "Node 3.2"}
,{"nodeKey": 33, "label": "Node 3.3"}
,{"nodeKey": 11, "label": "Node 1.1"}
]},
{"_id": 11, "nodeKey": 11, "label": "Node 1.1", "children": [{"nodeKey": 111, "label": "Node 1.1.1"}
,{"nodeKey": 112, "label": "Node 1.1.2"}
]
, "parents": [{"nodeKey": 1, "label": "Node 1"}
,{"nodeKey": 3, "label": "Node 3"}
]},
{"_id": 12, "nodeKey": 12, "label": "Node 1.2", "children": [{"nodeKey": 121, "label": "Node 1.2.1"}
,{"nodeKey": 122, "label": "Node 1.2.2"}
]
, "parents": [{"nodeKey": 1, "label": "Node 1"}
,{"nodeKey": 2, "label": "Node 2"}
]},
{"_id": 13, "nodeKey": 13, "label": "Node 1.3", "parents": [{"nodeKey": 1, "label": "Node 1"}]},
{"_id": 21, "nodeKey": 21, "label": "Node 2.1", "parents": [{"nodeKey": 2, "label": "Node 2"}]},
{"_id": 22, "nodeKey": 22, "label": "Node 2.2", "parents": [{"nodeKey": 2, "label": "Node 2"}]},
{"_id": 23, "nodeKey": 23, "label": "Node 2.3", "parents": [{"nodeKey": 2, "label": "Node 2"}]},
{"_id": 31, "nodeKey": 31, "label": "Node 3.1", "parents": [{"nodeKey": 1, "label": "Node 1"}
,{"nodeKey": 2, "label": "Node 2"}
,{"nodeKey": 3, "label": "Node 3"}]},
{"_id": 32, "nodeKey": 32, "label": "Node 3.2", "parents": [{"nodeKey": 3, "label": "Node 3"}]},
{"_id": 33, "nodeKey": 33, "label": "Node 3.3", "parents": [{"nodeKey": 3, "label": "Node 3"}]},
{"_id": 111, "nodeKey": 111, "label": "Node 1.1.1", "parents": [{"nodeKey": 11, "label": "Node 1.1"}]},
{"_id": 112, "nodeKey": 112, "label": "Node 1.1.2", "parents": [{"nodeKey": 11, "label": "Node 1.1"}]},
{"_id": 121, "nodeKey": 121, "label": "Node 1.2.1", "parents": [{"nodeKey": 12, "label": "Node 1.2"}]},
{"_id": 122, "nodeKey": 122, "label": "Node 1.2.2", "parents": [{"nodeKey": 12, "label": "Node 1.2"}]}
$ graphLookup似乎没有提供有关节点的直接父节点的任何信息。我使用了以下聚合管道,但未成功:
db.nodes.aggregate(
[{$match: {"nodeKey": 1}
}
,{$graphLookup : {
from : "nodes",
startWith : "$children.nodeKey",
connectFromField: "children.nodeKey",
connectToField : "nodeKey",
maxDepth : 5,
depthField : "depth",
as : "child"}
}
,{
$project: {
"_id" : 0
,"nodeKey" : 1
,"child.depth" : 1
,"child.nodeKey" : 1
,"child.label" : 1
}
}
]).pretty()
我正在寻找任何建议。感谢。
答案 0 :(得分:1)
您需要将收藏文档结构更改为引用nodekey's
和children
数组中的parents
。
像这样的东西
{"_id": 12, "nodeKey": 12, "label": "Node 1.2", "children": [121, 122], "parents": [1, 2]}
使用以下聚合查询。
这可以帮助你开始。我会让你使用它来获得你想要的输出。
重要的是要注意我们几次使用$graphLookup
次。第一次查找将为您提供childs
,接下来将为您提供parents
给孩子。
db.nodes.aggregate([
{$match: {"nodeKey": 1}},
{$graphLookup : {
from : "nodes",
startWith : "$children",
connectFromField: "children",
connectToField : "nodeKey",
maxDepth : 5,
as : "child"}
},
{$unwind:"$child"},
{$replaceRoot:{newRoot:"$child"}},
{$graphLookup : {
from : "nodes",
startWith : "$parents",
connectFromField: "parents",
connectToField : "nodeKey",
maxDepth : 5,
as : "parent"
}
},
{$project: {
_id : 0,
parentNodeKey : "$parent.nodeKey",
parentLabel : "$parent.label",
nodeLabel : "$label",
nodeKey : 1
}
}
]);
首次查找后的输出
{ "_id" : 121, "nodeKey" : 121, "label" : "Node 1.2.1", "parents" : [ 12 ] }
{ "_id" : 112, "nodeKey" : 112, "label" : "Node 1.1.2", "parents" : [ 11 ] }
{ "_id" : 122, "nodeKey" : 122, "label" : "Node 1.2.2", "parents" : [ 12 ] }
{ "_id" : 31, "nodeKey" : 31, "label" : "Node 3.1", "parents" : [ 1, 2, 3 ] }
{ "_id" : 12, "nodeKey" : 12, "label" : "Node 1.2", "children" : [ 121, 122 ], "parents" : [ 1, 2 ] }
{ "_id" : 111, "nodeKey" : 111, "label" : "Node 1.1.1", "parents" : [ 11 ] }
{ "_id" : 13, "nodeKey" : 13, "label" : "Node 1.3", "parents" : [ 1 ] }
{ "_id" : 11, "nodeKey" : 11, "label" : "Node 1.1", "children" : [ 111, 112 ], "parents" : [ 1, 3 ] }
最终输出
{ "nodeKey" : 121, "parentNodeKey" : [ 1, 2, 12 ], "parentLabel" : [ "Node 1", "Node 2", "Node 1.2" ], "nodeLabel" : "Node 1.2.1" }
{ "nodeKey" : 112, "parentNodeKey" : [ 1, 3, 11 ], "parentLabel" : [ "Node 1", "Node 3", "Node 1.1" ], "nodeLabel" : "Node 1.1.2" }
{ "nodeKey" : 122, "parentNodeKey" : [ 1, 2, 12 ], "parentLabel" : [ "Node 1", "Node 2", "Node 1.2" ], "nodeLabel" : "Node 1.2.2" }
{ "nodeKey" : 31, "parentNodeKey" : [ 3, 2, 1 ], "parentLabel" : [ "Node 3", "Node 2", "Node 1" ], "nodeLabel" : "Node 3.1" }
{ "nodeKey" : 12, "parentNodeKey" : [ 2, 1 ], "parentLabel" : [ "Node 2", "Node 1" ], "nodeLabel" : "Node 1.2" }
{ "nodeKey" : 111, "parentNodeKey" : [ 1, 3, 11 ], "parentLabel" : [ "Node 1", "Node 3", "Node 1.1" ], "nodeLabel" : "Node 1.1.1" }
{ "nodeKey" : 13, "parentNodeKey" : [ 1 ], "parentLabel" : [ "Node 1" ], "nodeLabel" : "Node 1.3" }
{ "nodeKey" : 11, "parentNodeKey" : [ 3, 1 ], "parentLabel" : [ "Node 3", "Node 1" ], "nodeLabel" : "Node 1.1" }