Neo4j 查找具有公共二级关系的节点的所有子树
我正在使用Neo4J数据库中的物料清单(BOM)和零件数据 我的图形中有3种类型的节点:Neo4j 查找具有公共二级关系的节点的所有子树,neo4j,tree,cypher,Neo4j,Tree,Cypher,我正在使用Neo4J数据库中的物料清单(BOM)和零件数据 我的图形中有3种类型的节点: (ItemUsageInstance)这些是物料清单树的元素 (项目)BOM表树上的每个唯一项目都有一个 (材料) 这些关系是: (ItemUsageInstance)-[CHILD\u OF]->(ItemUsageInstance) (ItemUsageInstance)-[INSTANCE\u]->(Item) (项目)-[MADE_FROM]->(材料) 模式如下图所示: 下面是数据的简化
这些是物料清单树的元素(ItemUsageInstance)
BOM表树上的每个唯一项目都有一个(项目)
(材料)
(ItemUsageInstance)-[CHILD\u OF]->(ItemUsageInstance)
(ItemUsageInstance)-[INSTANCE\u]->(Item)
(项目)-[MADE_FROM]->(材料)
ItemUsageInstance
s的子树,这些子树的项都是由相同的材料制作的
到目前为止,我的问题是:
MATCH (m:Material)
WITH m AS m
MATCH (m)<-[:MADE_FROM]-(i1:Item)<-[]-(iui1:ItemUsageInstance)-[:CHILD_OF]->(iui2:ItemUsageInstance)-[]->(i2:Item)-[:MADE_FROM]->(m) RETURN iui1, i1, iui2, i2, m
我期待第二个子树,碰巧也是一个链表,被包括在内。第二个子树由图>最右边的代码> iTimeSeaStudio材料制作而成,而且都是相同项的实例
我确认每个项usageinstance
节点都与项
节点有[实例]
关系:
MATCH (iui:ItemUsageInstance) WHERE NOT (iui)-[:INSTANCE_OF]->(:Item) RETURN iui
MATCH (i:Item) WHERE NOT (i)-[:MADE_FROM]->(:Material) RETURN i
(返回0条记录)
还确认每个项目
节点都与材料
节点有一个[制作自]
关系:
MATCH (iui:ItemUsageInstance) WHERE NOT (iui)-[:INSTANCE_OF]->(:Item) RETURN iui
MATCH (i:Item) WHERE NOT (i)-[:MADE_FROM]->(:Material) RETURN i
(返回0条记录)
确认inst7008
是唯一没有传出[CHILD\u OF]
关系的ItemUsageInstance
MATCH (iui:ItemUsageInstance) WHERE NOT (iui)-[:CHILD_OF]->(:ItemUsageInstance) RETURN iui
(返回1条记录:{“instance_id:“inst7008”}
)
inst5000
和inst7001
是唯一没有传入[CHILD\u OF]
关系的ItemUsageInstances
MATCH (iui:ItemUsageInstance) WHERE NOT (iui)<-[:CHILD_OF]-(:ItemUsageInstance) RETURN iui
MATCH(iui:ItemUsageInstance)如果在模式中没有(iui),则不考虑inst_5001和inst_7001之间的链接等情况。Inst_5001没有任何指向任何零件用法的链接,但您的匹配模式要求两种用法都有这样的链接。我想这就是你偏离正轨的地方。您找到的inst_5002树是因为它碰巧有一个指向您的模式所需的用法的链接
就“按子树聚合”而言,我将返回树根的ID(例如,ID(iui1)
,然后返回剩余的count(*)
,以显示给定根参与了多少子树。这是我经过大量编辑的查询:
MATCH path = (cinst:ItemUsageInstance)-[:CHILD_OF*1..]->(pinst:ItemUsageInstance), (m:Material)<-[:MADE_FROM]-(:Item)<-[:INSTANCE_OF]-(pinst)
WHERE ID(cinst) <> ID(pinst) AND ALL (x in nodes(path) WHERE ((x)-[:INSTANCE_OF]->(:Item)-[:MADE_FROM]->(m)))
WITH nodes(path) as insts, m
UNWIND insts AS instance
WITH DISTINCT instance, m
RETURN collect(instance), m
一个限制是它无法区分子树的根和子树。理想情况下,{“instance\u id”}
列表将按树中的深度排序。查找根很容易。匹配(根:ItemUsageInstance),其中不匹配()-[:CHILD\u of]->(根)
对于子级,可以通过指定最小距离0(默认值为1)来包含根
MATCH p=(root)-[:CHILD\u OF*0..25]->(ins),(m:Material)嗨,inst5001
与p001
有[INSTANCE OF]
关系。我确认每个ItemUsageInstance
节点都与Item
节点有关系:匹配(iui:ItemUsageInstance),其中不匹配(iui)-[:INSTANCE\u OF]->(:Item)RETURN iui
(返回0条记录)。还确认每个Item
节点与材质
节点具有[制作自]
关系:匹配(i:Item),其中不匹配(i)-[:制作自]->(:材质)返回i
(返回0条记录)。我不一定希望inst5001
和inst7001
之间有任何形式的链接(它们位于树的不同分支上)。添加了一个新图片,可以更好地查看这些关系。你是说匹配(根:ItemUsageInstance),p=(根)-[:CHILD\u of*0..25]>(ins),(m:Material)示例:inst5001
与inst7006
、inst7007
和inst7008
一起分组,作为材料M0001
的一部分。虽然这些材料由相同的材料制成,但在inst5001
和其他3种材料之间还有其他实例。因此inst7006
、inst7007
和inst7008
用公共材料组成子树,但inst5001
应与这些子树分开。此外,inst7006
、inst7007
和inst7008
在实例中出现两次list@tony_tiger第一步是肯定的,但我错过了分组部分。我更新了密码,将其分为两步。找到开始这是将所有数据分组到一个M0002
bucket中:(随后排序):{'instance\u id':'inst5000'},{'instance\u id':'inst5001'},{'instance\u id':'inst5002'},{'instance\u id':'inst7001'},{'instance\u id':'inst7002'},{'instance\u id':'inst7003'},{'instance_id':'inst7004'},{'instance_id':'inst7004'},{'instance_id':'inst7005'},{'instance_id':'inst7006'},{'instance_id':'inst7006'},{'instance_id':'inst7007'},{'instance_id':'inst7007'},{'instance_id':'inst7008'},{'instance_id':'inst7008'}
看起来,如果一个实例的项
是由material 2生成的,则会包含一次。如果一个项是公共material子树的一部分,则会再次包含该项,即使该公共material不是M0002
MATCH (root:ItemUsageInstance),
p=(root)<-[:CHILD_OF*0..25]-(ins),
(m:Material)<-[:MADE_FROM]-(:Item)<-[:INSTANCE_OF]-(ins)
WHERE NOT ()<-[:CHILD_OF]-(root)
AND NOT (m:Material)<-[:MADE_FROM]-(:Item)<-[:INSTANCE_OF]-()<-[:CHILD_OF]-(ins)
MATCH p2=(ins)<-[:CHILD_OF*1..25]-(cins)
WHERE ALL(n in NODES(p2) WHERE (m)<-[:MADE_FROM]-(:Item)<-[:INSTANCE_OF]-(n))
WITH ins, cins, SIZE(NODES(p2)) as depth, m ORDER BY depth ASC
RETURN ins as collection_head, ins+COLLECT(cins) as instances, m as material