获取 Neo4J 中特定类型的所有子图
Get all subgraphs of a particular type in Neo4J
我有一组节点和关系,我想获取节点的特定类型的子图。为了解释这个问题,附上图表的图像。
黄色节点通过关系 "IS_PART_OF" 与绿色节点相连。当我们查看上面的片段时,黄色节点“8366854”由 4 个绿色节点 "P10398"、"P10398-2"、"A0A024" 和 "P02647" 连接,其中连接黄色节点“8366931”通过 2 个绿色节点 "A0A024" 和 "P02647"。所以绿色节点 "A0A024" 和 "P02647" 是两者共有的,我可以说黄色节点“8366931”是“8366854”的子节点。仅当所有绿色节点对两者都通用时才会发生这种情况。
所以我的查询将是一个黄色节点id说“8366854”,其中returns所有子黄色节点(在这种情况下只有“8366931”)。
所以对于下面的片段,我可以这样说,
1) “8366523”是“8366848”的子项
2) “8366915”不是“8366848”的子节点,因为它没有所有绿色节点都是公共的。
实际上,密码允许您通过一系列指令来表达:
- 取黄色节点并取其所有绿色邻居
- 为每个绿色邻居找到黄色及其绿色邻居
- 确保对于第二个黄色邻居,每个绿色邻居也是第一个黄色节点的邻居
MATCH (Y1:YELLOW)<-[:IS_PART_OF]-(G:GREEN)
WITH Y1,
collect(G) AS greens1
UNWIND greens1 AS G
MATCH (G)-[:IS_PART_OF]->(Y2:YELLOW)<-[:IS_PART_OF]-(G2:GREEN) WHERE Y1 <> Y2
WITH Y1, Y2, greens1,
collect(G2) AS greens2
WHERE SIZE(greens1) > size(greens2) AND
ALL(G IN greens2 WHERE G IN greens1)
RETURN Y1, collect(Y2) AS subs
1。创建图表:
第一个语句创建节点,第二个语句创建它们之间的关系。
CREATE
(Yellow1:Yellow {name: 'Yellow 1'}),
(Yellow2:Yellow {name: 'Yellow 2'}),
(Yellow3:Yellow {name: 'Yellow 3'}),
(Yellow4:Yellow {name: 'Yellow 4'}),
(Yellow5:Yellow {name: 'Yellow 5'}),
(Yellow6:Yellow {name: 'Yellow 6'}),
(Green1:Green {name: 'Green 1'}),
(Green2:Green {name: 'Green 2'}),
(Green3:Green {name: 'Green 3'}),
(Green4:Green {name: 'Green 4'}),
(Green5:Green {name: 'Green 5'}),
(Green6:Green {name: 'Green 6'}),
(Green7:Green {name: 'Green 7'}),
(Green8:Green {name: 'Green 8'}),
(Green9:Green {name: 'Green 9'}),
(Green10:Green {name: 'Green 10'}),
(Green11:Green {name: 'Green 11'}),
(Green12:Green {name: 'Green 12'}),
(Green13:Green {name: 'Green 13'})
CREATE
// upper graph
(Green1)-[:IS_PART_OF]->(Yellow1),
(Green2)-[:IS_PART_OF]->(Yellow1),
(Green3)-[:IS_PART_OF]->(Yellow1),
(Green4)-[:IS_PART_OF]->(Yellow1),
(Green3)-[:IS_PART_OF]->(Yellow2),
(Green4)-[:IS_PART_OF]->(Yellow2),
// lower graph
(Green5)-[:IS_PART_OF]->(Yellow3),
(Green6)-[:IS_PART_OF]->(Yellow3),
(Green5)-[:IS_PART_OF]->(Yellow4),
(Green6)-[:IS_PART_OF]->(Yellow4),
(Green7)-[:IS_PART_OF]->(Yellow4),
(Green8)-[:IS_PART_OF]->(Yellow4),
(Green7)-[:IS_PART_OF]->(Yellow5),
(Green8)-[:IS_PART_OF]->(Yellow5),
(Green9)-[:IS_PART_OF]->(Yellow5),
(Green10)-[:IS_PART_OF]->(Yellow5),
(Green11)-[:IS_PART_OF]->(Yellow5),
(Green12)-[:IS_PART_OF]->(Yellow5),
(Green8)-[:IS_PART_OF]->(Yellow6),
(Green13)-[:IS_PART_OF]->(Yellow6);
2。建议的解决方案:
2.1 基本思想:
对于黄色节点 "this" 比较与另一个黄色节点的关系数量 "that" 与节点 所有 关系的数量 "this".如果数量相等,则节点 "this" 是 "that".
的子节点
2.2 说明:
- 识别两个黄色节点之间的所有对
- 识别黄色-黄色对中的所有绿色节点
- 计算黄-黄对中绿色节点的数量
- 识别被检黄色节点的所有关系
- 统计被检黄色节点的所有关系的数量
- 过滤那些黄-黄对,其中所有关系的数量等于对关系的数量
2.3 密码语句:
// |-------------------------------------- (1) ---------------------------------------|
MATCH yellowPairPath = (yellowA:Yellow)<-[pairRelation:IS_PART_OF]-(:Green)-[:IS_PART_OF]->(yellowB:Yellow)
WITH DISTINCT yellowA, yellowB, pairRelation
// |-------- (2) --------|
WITH yellowA, startNode(pairRelation) AS pairRelations, yellowB
// |------- (3) ------|
WITH yellowA, count(pairRelations) AS pairRelationAmount, yellowB
// |---------------------- (4) -----------------------|
MATCH (yellowA:Yellow)<-[allRelations:IS_PART_OF]-(:Green)
// |------ (5) ------|
WITH yellowA, pairRelationAmount, count(allRelations) AS allRelationsAmount, yellowB
// |---------------- (6) ----------------|
WHERE pairRelationAmount = allRelationsAmount
RETURN yellowA, yellowB;
3。结果:
根据您的要求,对于列出的节点,结果必须解释为 "YellowA is a sub of YellowB"。
╒═══════════════════╤═══════════════════╕
│"yellowA" │"yellowB" │
╞═══════════════════╪═══════════════════╡
│{"name":"Yellow 2"}│{"name":"Yellow 1"}│
├───────────────────┼───────────────────┤
│{"name":"Yellow 3"}│{"name":"Yellow 4"}│
└───────────────────┴───────────────────┘
我有一组节点和关系,我想获取节点的特定类型的子图。为了解释这个问题,附上图表的图像。
黄色节点通过关系 "IS_PART_OF" 与绿色节点相连。当我们查看上面的片段时,黄色节点“8366854”由 4 个绿色节点 "P10398"、"P10398-2"、"A0A024" 和 "P02647" 连接,其中连接黄色节点“8366931”通过 2 个绿色节点 "A0A024" 和 "P02647"。所以绿色节点 "A0A024" 和 "P02647" 是两者共有的,我可以说黄色节点“8366931”是“8366854”的子节点。仅当所有绿色节点对两者都通用时才会发生这种情况。
所以我的查询将是一个黄色节点id说“8366854”,其中returns所有子黄色节点(在这种情况下只有“8366931”)。
所以对于下面的片段,我可以这样说,
1) “8366523”是“8366848”的子项
2) “8366915”不是“8366848”的子节点,因为它没有所有绿色节点都是公共的。
实际上,密码允许您通过一系列指令来表达:
- 取黄色节点并取其所有绿色邻居
- 为每个绿色邻居找到黄色及其绿色邻居
- 确保对于第二个黄色邻居,每个绿色邻居也是第一个黄色节点的邻居
MATCH (Y1:YELLOW)<-[:IS_PART_OF]-(G:GREEN)
WITH Y1,
collect(G) AS greens1
UNWIND greens1 AS G
MATCH (G)-[:IS_PART_OF]->(Y2:YELLOW)<-[:IS_PART_OF]-(G2:GREEN) WHERE Y1 <> Y2
WITH Y1, Y2, greens1,
collect(G2) AS greens2
WHERE SIZE(greens1) > size(greens2) AND
ALL(G IN greens2 WHERE G IN greens1)
RETURN Y1, collect(Y2) AS subs
1。创建图表:
第一个语句创建节点,第二个语句创建它们之间的关系。
CREATE
(Yellow1:Yellow {name: 'Yellow 1'}),
(Yellow2:Yellow {name: 'Yellow 2'}),
(Yellow3:Yellow {name: 'Yellow 3'}),
(Yellow4:Yellow {name: 'Yellow 4'}),
(Yellow5:Yellow {name: 'Yellow 5'}),
(Yellow6:Yellow {name: 'Yellow 6'}),
(Green1:Green {name: 'Green 1'}),
(Green2:Green {name: 'Green 2'}),
(Green3:Green {name: 'Green 3'}),
(Green4:Green {name: 'Green 4'}),
(Green5:Green {name: 'Green 5'}),
(Green6:Green {name: 'Green 6'}),
(Green7:Green {name: 'Green 7'}),
(Green8:Green {name: 'Green 8'}),
(Green9:Green {name: 'Green 9'}),
(Green10:Green {name: 'Green 10'}),
(Green11:Green {name: 'Green 11'}),
(Green12:Green {name: 'Green 12'}),
(Green13:Green {name: 'Green 13'})
CREATE
// upper graph
(Green1)-[:IS_PART_OF]->(Yellow1),
(Green2)-[:IS_PART_OF]->(Yellow1),
(Green3)-[:IS_PART_OF]->(Yellow1),
(Green4)-[:IS_PART_OF]->(Yellow1),
(Green3)-[:IS_PART_OF]->(Yellow2),
(Green4)-[:IS_PART_OF]->(Yellow2),
// lower graph
(Green5)-[:IS_PART_OF]->(Yellow3),
(Green6)-[:IS_PART_OF]->(Yellow3),
(Green5)-[:IS_PART_OF]->(Yellow4),
(Green6)-[:IS_PART_OF]->(Yellow4),
(Green7)-[:IS_PART_OF]->(Yellow4),
(Green8)-[:IS_PART_OF]->(Yellow4),
(Green7)-[:IS_PART_OF]->(Yellow5),
(Green8)-[:IS_PART_OF]->(Yellow5),
(Green9)-[:IS_PART_OF]->(Yellow5),
(Green10)-[:IS_PART_OF]->(Yellow5),
(Green11)-[:IS_PART_OF]->(Yellow5),
(Green12)-[:IS_PART_OF]->(Yellow5),
(Green8)-[:IS_PART_OF]->(Yellow6),
(Green13)-[:IS_PART_OF]->(Yellow6);
2。建议的解决方案:
2.1 基本思想:
对于黄色节点 "this" 比较与另一个黄色节点的关系数量 "that" 与节点 所有 关系的数量 "this".如果数量相等,则节点 "this" 是 "that".
的子节点2.2 说明:
- 识别两个黄色节点之间的所有对
- 识别黄色-黄色对中的所有绿色节点
- 计算黄-黄对中绿色节点的数量
- 识别被检黄色节点的所有关系
- 统计被检黄色节点的所有关系的数量
- 过滤那些黄-黄对,其中所有关系的数量等于对关系的数量
2.3 密码语句:
// |-------------------------------------- (1) ---------------------------------------|
MATCH yellowPairPath = (yellowA:Yellow)<-[pairRelation:IS_PART_OF]-(:Green)-[:IS_PART_OF]->(yellowB:Yellow)
WITH DISTINCT yellowA, yellowB, pairRelation
// |-------- (2) --------|
WITH yellowA, startNode(pairRelation) AS pairRelations, yellowB
// |------- (3) ------|
WITH yellowA, count(pairRelations) AS pairRelationAmount, yellowB
// |---------------------- (4) -----------------------|
MATCH (yellowA:Yellow)<-[allRelations:IS_PART_OF]-(:Green)
// |------ (5) ------|
WITH yellowA, pairRelationAmount, count(allRelations) AS allRelationsAmount, yellowB
// |---------------- (6) ----------------|
WHERE pairRelationAmount = allRelationsAmount
RETURN yellowA, yellowB;
3。结果:
根据您的要求,对于列出的节点,结果必须解释为 "YellowA is a sub of YellowB"。
╒═══════════════════╤═══════════════════╕
│"yellowA" │"yellowB" │
╞═══════════════════╪═══════════════════╡
│{"name":"Yellow 2"}│{"name":"Yellow 1"}│
├───────────────────┼───────────────────┤
│{"name":"Yellow 3"}│{"name":"Yellow 4"}│
└───────────────────┴───────────────────┘