【问题标题】:Create graph from subset of existing nodes从现有节点的子集创建图形
【发布时间】:2015-06-29 19:56:50
【问题描述】:

我有一个包含 2 种节点的有向 Neo4j 图:Set 1 中带有标签的节点和 Set 2 中带有标签的节点。我想在 Set 1 中的节点之间创建新边(新类型),每当有从 Set 1 节点到另一个 Set 1 节点的有向路径仅通过 Set 2 节点(可能有 0 个这样的 Set 2 节点)。

这是一个示例数据集:

CREATE (a:A {id:"a"})-[:CONN]->(t1:T {id:"t1"}),
   (t1)-[:CONN]->(b1:B {id:"b1"}),
   (b1)-[:CONN]->(t2:U {id:"t1"}),
   (t2)-[:CONN]->(c1:C {id:"c1"}),
   (c1)-[:CONN]->(t3:T {id:"t3"}),
   (t3)-[:CONN]->(d1:D {id:"d1"}),
   (t3)-[:CONN]->(d2:D {id:"d2"}),
   (d1)-[:CONN]->(t4:T {id:"t4"}),
   (d2)-[:CONN]->(t4),
   (t4)-[:CONN]->(e1:E {id:"e1"}),
   (t4)-[:CONN]->(e2:E {id:"e2"})

在这个例子中,ABCD、&E 在第 1 组中,T&U 在第 2 组中,所以我想画新的:AGG 边缘像这样:

MATCH (a:A {id:"a"}), (b1:B {id:"b1"}), (c1:C {id:"c1"}), (d1:D {id:"d1"}),
      (d2:D {id:"d2"}), (e1:E {id:"e1"}), (e2:E {id:"e2"})
CREATE (a)-[:AGG]->(b1),
   (b1)-[:AGG]->(c1),
   (c1)-[:AGG]->(d1),
   (c1)-[:AGG]->(d2),
   (d1)-[:AGG]->(e1),
   (d1)-[:AGG]->(e2),
   (d2)-[:AGG]->(e1),
   (d2)-[:AGG]->(e2)

关于CONN 边,我知道该图是一个有向无环图,所以我不必担心循环。

这可以在 Cypher 中完成吗?或者有人可以通过 Java 接口提出一种有效的方法(例如遍历策略)?谢谢。

【问题讨论】:

    标签: neo4j cypher traversal


    【解决方案1】:

    是的,它可以完成 - 这是一个复杂的查询,因此您可能需要稍微尝试一下,但这里有一些东西可以开始。也许其他人可以来改进这一点,但我认为这应该完成大部分基本逻辑。

    MATCH p=(node1)-[*]-(node2)
    WHERE ('A' in labels(node1) OR
           'B' in labels(node1) OR
           'C' in labels(node1) OR
           'D' in labels(node1) OR
           'E' in labels(node1)) 
          AND
          ('A' in labels(node2) OR
           'B' in labels(node2) OR
           'C' in labels(node2) OR
           'D' in labels(node2) OR
           'E' in labels(node2)) 
          AND
          (length(p) = 1 OR 
           all(intermedNode in 
               filter(n IN tail(nodes(p)) WHERE n <> last(nodes(p)))
               WHERE
               ('T' in labels(intermedNode) OR
                'U' in labels(intermedNode))))
    WITH node1, node2
    CREATE node1-[:MyNewNiftyEdge]->node2;
    

    解释:

    1. 我们正在寻找路径;前两个 WHERE 大块只是证明路径的源和目标都必须在“Set1”中。
    2. WHERE 块的最后一部分做了所有有趣的事情。长度为 1 的路径是可以的(零个中间“Set2”节点)。但是如果有中间节点,我们要做的是检查是否所有的“内部”节点都是“Set2”。带有tail 表达式的filter 位只是切断路径中的第一个和最后一个节点(我们已经知道这是node1node2)。然后all 表达式坚持如果中间有任何东西,它必须是Set2 节点(标记为“T”或“U”)。
    3. 最后,通过这两个匹配的节点,我们创建了一个直接连接它们的漂亮新关系。

    【讨论】:

    • 太棒了,谢谢。我也开始使用 Java 接口编写一个解决方案,如果可行的话,我也可以在这里发布。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多