在Neo4j中使用多个关系中的Where子句

时间:2015-11-06 10:37:15

标签: neo4j cypher graph-databases

显然,以下WHERE子句似乎不起作用,因为我们的查询中有两个关系(WorksAt和ResponsibleFor)。如果只有一种关系,那么这就像魔法一样。在下面的查询中,查询返回部门科学中的所有课程,但它不会过滤掉Maria Smith未教授的课程。我想做的只是获得在科学系工作的Maria Smith教授的课程。  我遇到了似乎是潜在候选条款的WITH和Start子句,使其可以在将查询的一部分过滤掉之前将其发送到另一部分。
 http://neo4j.com/docs/stable/query-with.html
但我还没有掌握这个概念。任何人都可以寻求帮助吗?

MATCH (d:Department)<-[w:WorksAt]-(t:Tutor)-[r:ResponsibleFor]->(c:Courses) 
WHERE d.name='Science' 
AND  t.name='Maria Smith'
return  c,r

2 个答案:

答案 0 :(得分:5)

有很多方法可以为这只特殊的猫提供皮肤。让我们分解吧。

找一位名字叫玛丽亚史密斯的导师。这在科学&#39;科学&#39;系

MATCH (d:Department)<-[:WorksAt]-(t:Tutor)
WHERE d.name = 'Science' AND t.name = 'Maria Smith'
RETURN t

找到导师教授的课程

MATCH (t:Tutor)-[:ResponsibleFor]->(c:Courses)
RETURN t.name, c

将这两者结合起来,以获得Scence部门的Maria Smith教授的课程

MATCH (d:Department)<-[:WorksAt]-(t:Tutor)
WHERE d.name = 'Science' AND t.name = 'Maria Smith'
WITH t
MATCH (t)-[r:ResponsibleFor]->(c:Courses)
RETURN t.name, r, c

这也可以写成

MATCH (d:Department { name : 'Science' })<-[:WorksAt]-(t:Tutor { name : 'Maria Smith' })
WITH t
MATCH (t)-[r:ResponsibleFor]->(c:Courses)
RETURN t.name, r, c

为了最大限度地提高查询性能,您可以使用架构索引快速找到Department和Tutor节点。你在做这个吗?要创建索引,请使用

CREATE INDEX ON :Department(name)
CREATE INDEX ON :Tutor(name)

分别运行这些行。

如果您想要列出每个导师所教授的课程,如上面第二个查询中所建议的那样,您可以使用以下查询来汇总每个导师的课程。

MATCH (t:Tutor)-[:ResponsibleFor]->(c:Courses)
RETURN t.name as CourseTutor, collect(c.name) as CourseName

希望这有帮助。

答案 1 :(得分:1)

很好的故障。有关此类查询的效果详情,请参阅Wes Freeman的Pragmatic Cypher Optimization。在设置匹配时,从较小的节点集开始,向更大的节点集开始工作(Wes&#39;规则4)。