获取 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 说明:

  1. 识别两个黄色节点之间的所有对
  2. 识别黄色-黄色对中的所有绿色节点
  3. 计算黄-黄对中绿色节点的数量
  4. 识别被检黄色节点的所有关系
  5. 统计被检黄色节点的所有关系的数量
  6. 过滤那些黄-黄对,其中所有关系的数量等于对关系的数量

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"}│
└───────────────────┴───────────────────┘