Neo4j匹配节点属性或关系属性

时间:2014-04-08 22:38:57

标签: properties neo4j match relationship cypher

我正在尝试编写一个返回与节点属性或关系属性匹配的节点的查询。

例如,如果关系属性状态为“good”,我想要name属性为George OR的所有节点。我有两个查询将获取每个节点的节点:

MATCH (n) where n.name = 'George' return n

MATCH (n)-[r]-() where r.status = 'good' return n 

我可以编写一个简单的查询来获得这些组合结果吗?我以为我可以使用这个可选查询(下面),但我似乎误解了可选匹配子句,因为我只从第一个查询中获取节点。

MATCH (n) where n.name = 'George' 
Optional MATCH (n)-[r]-() where r.status = 'good' return distinct n 

1 个答案:

答案 0 :(得分:7)

当可选匹配发生时,唯一可以进行可选匹配的n个节点是已经与第一个条件匹配的节点。你可以做到

MATCH (n)
WHERE n.name = 'George' OR n-[{ status:"good" }]->()
RETURN n

但是对于较大的图表,请记住这不会有效地使用索引。

另一种方式是

MATCH (n {name:"George"})
RETURN n
UNION MATCH (n)-[{status:"good"})->()
RETURN n

假设您使用标签并设置相关索引(但第二部分仍然可能非常低效),这应该可以更好地使用第一个匹配的索引。

修改
重新评论,关系索引将使这部分更快,更正确,但在我看来,最好说它很慢,因为模式不确定。第二个匹配模式类似于

  • 将图表中的每个节点绑定到(n)
  • (n)
  • 获取所有传出关系(不论类型)
  • 检查status="good"
  • 的关系

您可以通过关系索引来提高性能,但由于关系仅存在于它关联的两个节点之间,因此您可以将其视为由这些节点编制索引。也就是说,通过排除关系不相关的节点来修复第一个项目符号点。两个匹配条款可能看起来像

MATCH (n:Person {name:"George"})  
       // add label to use index
MATCH (n:Person)-[{status:"good"}]->() 
       // add label to limit (n) -no indexing, but better than unlimited (n)
MATCH (n:Person {name:"Curious"})-[{status:"good"}]->()
       // add label to use index -now the relationships are sort-of-indexed

和/或输入关系

MATCH (n)-[:REL {status:"good"}]->() // add type to speed up relationship retrieval

事实上,使用匿名关系和rel属性,将属性作为类型可能是有意义的(第三点),所以

MATCH (n)-[:GOOD]->() // absent type, it would make sense to use the property as type instead

您的实际查询可能看起来非常不同,而您的问题根本不是关于查询性能的问题:)哦哦。