【问题标题】:Neo4j Cypher : listing edgesNeo4j Cypher:列出边缘
【发布时间】:2017-01-22 20:18:27
【问题描述】:

例如拥有这些数据:

CREATE
(p1:Person {name:"p1"}),
(p2:Person {name:"p2"}),
(p3:Person {name:"p3"}),
(p4:Person {name:"p4"}),
(p5:Person {name:"p5"}),
(p1)-[:KNOWS]->(p2),
(p1)-[:KNOWS]->(p3),
(p1)-[:KNOWS]->(p4),
(p5)-[:KNOWS]->(p3),
(p5)-[:KNOWS]->(p4)

我想得到 p1 和 p5 之间的共同关系:

MATCH (p1:Person {name:"p1"})-[r1:KNOWS]-(p:Person)-[r2:KNOWS]-(p5:Person {name:"p5"})
RETURN p, p1, p5

这将返回 4 个节点:p1、p3、p4、p5 和 4 条边。

我的目标是获得具有方向的边缘作为表格行:从和到。所以这似乎有效:

MATCH (p1:Person {name:"p1"})-[r1:KNOWS]-(p:Person)-[r2:KNOWS]-(p5:Person {name:"p5"})
RETURN startNode(r1).name AS from, endNode(r1).name AS to
UNION
MATCH (p1:Person {name:"p1"})-[r1:KNOWS]-(p:Person)-[r2:KNOWS]-(p5:Person {name:"p5"})
RETURN startNode(r2).name AS from, endNode(r2).name AS to

结果是一个表格:

from | to
-----|----
p1   | p3
p1   | p4
p5   | p3
p5   | p4

我的问题是:

  • 对吗?
  • 这是最好的方法吗?我的意思是当有数千个节点时的性能。
  • 如果我想要三个人的公共节点怎么办?

【问题讨论】:

    标签: neo4j cypher


    【解决方案1】:

    检查性能的最佳方法是PROFILE您的查询。

    对吗?

    我不确定你为什么要使用 UNION,你可以轻松地使用路径检查:

    PROFILE MATCH (p1:Person {name:"p1"}), (p5:Person {name:"p5"})
    MATCH path=(p1)-[*..2]-(p5)
    UNWIND rels(path) AS r
    RETURN startNode(r).name AS from, endNode(r).name AS to
    

    这是最好的方法吗?我的意思是当有数千个节点时的性能。

    通常,您首先会通过单个查找匹配所需路径的开始节点和结束节点(确保您在 Person 节点的标签/属性对上具有索引/约束)。 根据您的图表程度,这可能是一项广泛的操作,您可以通过限制路径的最大深度来进行微调 *..15

    如果我想要三个人的公共节点怎么办?

    根据图表的大小,有多种方法:

    a) 如果没有太多节点:

    匹配 3 个节点并找到与 ALL 3 至少有一个连接的 Person:

    PROFILE MATCH (p:Person) WHERE p.name IN ["p1","p4","p3"]
    WITH collect(p) AS persons
    MATCH (p:Person) WHERE ALL(x IN persons WHERE EXISTS((x)--(p)))
    RETURN p
    

    b) 一些调整,假设一个公共将直接连接到 3 中的第一个节点

    PROFILE MATCH (p:Person) WHERE p.name IN ["p1","p4","p3"]
    WITH collect(p) AS persons
    WITH persons, persons[0] as p
    MATCH (p)-[:KNOWS]-(other)
    WHERE ALL (x IN persons WHERE EXISTS((x)--(other)))
    RETURN other
    

    c) 如果您需要多深度路径中的公地:

    PROFILE MATCH (p:Person) WHERE p.name IN ["p1","p4","p3"]
    WITH collect(p) AS persons
    WITH persons, persons[0] as p1, persons[1] as p2
    MATCH path=(p1)-[*..15]-(p2)
    WHERE ANY(x IN nodes(path) WHERE x = persons[2])
    UNWIND rels(path) AS commonRel
    WITH distinct commonRel AS r
    RETURN startNode(r) AS from, endNode(r) AS to
    

    我建议扩大您的图表并尝试/调整您的用例

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多