【问题标题】:Get all subgraphs of a particular type in Neo4J在 Neo4J 中获取特定类型的所有子图
【发布时间】:2018-09-21 10:45:42
【问题描述】:

我有一组节点和关系,我想为节点获取特定类型的子图。为了解释这个问题,附上图表的图像。

黄色节点由绿色节点通过关系“IS_PART_OF”连接。当我们查看上面的片段时,黄色节点“8366854”由 4 个绿色节点“P10398”、“P10398-2”、“A0A024”和“P02647”连接,其中黄色节点“8366931”由 2 个绿色节点“A0A024”连接”和“P02647”。所以绿色节点“A0A024”和“P02647”对两者都是通用的,我可以说黄色节点“8366931”是“8366854”的子节点。仅当所有绿色节点对两者都通用时才会发生这种情况。

所以我的查询将是一个黄色节点 id 说“8366854”,返回所有子黄色节点(在这种情况下只有“8366931”)。

所以对于下面的片段,我可以说,

1) “8366523”是“8366848”的子类

2) “8366915”不是“8366848”的子节点,因为它没有共同的所有绿色节点。

【问题讨论】:

  • ……你已经尝试了什么?

标签: graph neo4j cypher subgraph


【解决方案1】:

实际上,密码允许您通过一系列指令来表达这一点:

  • 取黄色节点并取走他所有的绿色邻居
  • 为每个绿色邻居找到黄色及其绿色邻居
  • 确保对于第二个黄色邻居,每个绿色邻居也是第一个黄色节点的邻居

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

【讨论】:

    【解决方案2】:

    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 是 YellowB 的子节点”。

    ╒═══════════════════╤═══════════════════╕
    │"yellowA"          │"yellowB"          │
    ╞═══════════════════╪═══════════════════╡
    │{"name":"Yellow 2"}│{"name":"Yellow 1"}│
    ├───────────────────┼───────────────────┤
    │{"name":"Yellow 3"}│{"name":"Yellow 4"}│
    └───────────────────┴───────────────────┘
    

    【讨论】:

    • 感谢@ThirstForKnowledge 为什么我们需要使用pairRelation 和startNode 然后使用绿色节点的计数而不是直接使用如下,code MATCH yellowPairPath = (yellowA:Yellow)(yellowB:Yellow) WITH DISTINCT yellowA, yellowB, pairRelation WITH yellowA, green AS greenNode, yellowB WITH yellowA, count(greenNode) AS pairRelationAmount, yellowB code
    • @SreenathS,感谢您的额外询问!您提议的 Cypher 语句将找到两个黄色节点之间的所有路径并计算它们包含的绿色节点。它不包括可能的更多绿色节点到黄色节点之一。根据您的要求,如果黄色节点共享所有绿色节点,则它们只是另一个黄色节点的子节点。由于您提出的陈述中没有提出这种比较,因此很遗憾您无法再识别任何子项。因此,您需要 pairRelationstartNode 部分。
    • 我的 Cypher 语句背后的想法可以概括如下:对于黄色节点“this”,将关系的数量与另一个黄色节点“that”的数量与 all i> 节点“this”的关系。如果数量相等,则节点“this”是“that”的子节点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-06
    • 2015-11-16
    • 2013-09-20
    • 2021-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多