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

问题描述:

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

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

看起来不错。尝试返回*而不是c,r –

+0

除此之外,你确定所有的情况都符合标签,属性和关系类型吗? –

+0

@DaveBennett返回*将带来与返回c,r相同的结果。此外,标签,属性和关系类型与案例相匹配,因为我知道Neo4j Cypher查询不区分大小写,而且查询语法不区分大小写,但也包含我们放入的值 – Sike12

有很多方法可以为这只特定的猫蒙皮。让我们分解它。

找到他的名字是“玛丽亚·史密斯”,在“科学”部门

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 

希望这会有所帮助。

+0

嗨@ceej谢谢你你的答案。一旦我完全测试,我会让你知道。 – Sike12

细分。有关此类查询的性能详细信息,请参阅Wes Freeman的Pragmatic Cypher Optimization。在建立比赛时,先从较小的节点集开始,朝着更大的(Wes的规则4)工作。

+0

谢谢@HieroB。 – Sike12