匹配多个独立(或从属)路径

时间:2015-02-19 17:55:02

标签: neo4j cypher

我正在查看人员和组织的层次结构,并试图找到他们在何处/是否会面并共享管理。让我们说" Bob"和"苏珊"为不同的分支工作。如果/当它们重叠时,我想通过公司展示他们的两个报告关系。

此查询目前效果很好,并返回单个路径:

MATCH path=(p:Person {name: "Bob"})-[:reports_to*]->(o:Organization {code: "TopOfCompany"})
RETURN path;

此查询也很有效,并返回单个路径:

MATCH path2=(p:Person {name: "Susan"})-[:reports_to*]->(o2:Organization {code: "TopOfCompany"})
RETURN path2;

此查询(在一次操作中执行这两项操作)根本不返回任何内容:

MATCH path=(p:Person {name: "Bob"})-[:reports_to*]->(o:Organization {code: "TopOfCompany"}),
      path2=(p:Person {name: "Susan"})-[:reports_to*]->(o2:Organization {code: "TopOfCompany"})
RETURN path,path2;

如果我在第二个路径查询中重用第一个o绑定,情况也是如此。

我知道我可以重新制定这个以找到两个人在中间相遇的地方,如下:

MATCH path=(p1:Person {name: "Bob"})-[:reports_to*]->(o:Organization)<-[:reports_to*]-(p2:Person {name: "Susan"})
RETURN path;

确实该查询运行正常 - 但如果他们不在中间见面,则此查询将失败,因为中间的o:Organization不存在。

我可能有其他等效方法可以重新制定以获得正确的结果 - 但我的问题的核心是,是不是可以在一个查询中识别两个不同的独立路径?这会在他们不相遇的情况下很有用,我匹配的目标(&#34; TopOfCompany&#34;)不同,或者我只想比较一系列路径。

哦,我在2.2M04上使用服务器。具有两个路径的查询成功,但结果为空,因为结果的JSON版本为:

{"columns":["path","path2"],"data":[],"stats":{"contains_updates":false,"nodes_created":0,"nodes_deleted":0,"properties_set":0,"relationships_created":0,"relationship_deleted":0,"labels_added":0,"labels_removed":0,"indexes_added":0,"indexes_removed":0,"constraints_added":0,"constraints_removed":0}}

2 个答案:

答案 0 :(得分:4)

您的此查询对pBob节点使用相同的变量(Susan),这可能解释了为什么它不能按预期工作(单个节点不能对于同一属性有2个不同的值):

MATCH path=(p:Person {name: "Bob"})-[:reports_to*]->(o:Organization {code: "TopOfCompany"}),
      path2=(p:Person {name: "Susan"})-[:reports_to*]->(o2:Organization {code: "TopOfCompany"})
RETURN path,path2;

你可以使用不同的变量,也可以完全摆脱节点变量(因为你不能在任何地方使用它们) - 就像这样:

MATCH path=(:Person {name: "Bob"})-[:reports_to*]->(:Organization {code: "TopOfCompany"}),
      path2=(:Person {name: "Susan"})-[:reports_to*]->(:Organization {code: "TopOfCompany"})
RETURN path,path2;

答案 1 :(得分:1)

在使用路径匹配时,可以使用

Optional Match,它可以被认为是SQL中外连接的Cypher等效项。以下查询匹配两个单独的路径以及与两个人匹配的路径:

MATCH 
    path1=(p1:Person {name: "Bob"})-[:reports_to*]->(o1:Organization {code: "TopOfCompany"})
OPTIONAL MATCH
    path2=(p2:Person {name: "Susan"})-[:reports_to*]->(o2:Organization {code: "TopOfCompany"})
OPTIONAL MATCH
    path3=(p1)-[:reports_to*]->(o:Organization {code: "TopOfCompany"})<-[:reports_to*]-(p2)
RETURN path1, path2, path3;