如何根据关系返回不同的节点?

时间:2019-04-09 09:05:44

标签: neo4j cypher

在电影数据库中,我使用Cypher查询在Person节点上创建了一个自我关系(ACTED_WITH)。

MATCH (p1:Person)-[:ACTED_IN]->(m:Movie)
MATCH (p2:Person)-[:ACTED_IN]->(m)
WHERE p2 <> p1
OPTIONAL MATCH (p1)-[r:ACTED_WITH]-(p2)
FOREACH (n IN (CASE WHEN r IS NULL THEN [0] ELSE [] END) |
MERGE (p1)-[:ACTED_WITH]-(p2)  
)

我想退回具有ACTED_WITH关系的电影(Cloud Atlas)的所有演员,但没有重复吗?

这是我尝试过的密码查询

MATCH (m)-[:ACTED_IN]-(a1)-[r]-(a2)-[:ACTED_IN]-(m)
WHERE m.title="Cloud Atlas" RETURN a1,a2

查询两次返回Tom Hanks和Hugo Weaving(可能是由于双向关系?)。

"a1","a2"                                
{"name":"Tom Hanks","born":1956}, {"name":"Hugo Weaving","born":1960} 

{"name":"Hugo Weaving","born":1960}, {"name":"Tom Hanks","born":1956}

预期结果

"a1", "a2"                                
{"name":"Tom Hanks","born":1956}, {"name":"Hugo Weaving","born":1960} 

如何更改我的查询,以使Tom Hanks和Hugo Weaving仅返回一次?朝正确方向的任何见解都受到高度赞赏。谢谢。

2 个答案:

答案 0 :(得分:2)

使用定向和命名 (如果人与人之间存在其他关系) Actor节点之间的关系:

MATCH (m:Movie)<-[:ACTED_IN]-(a1:Person)-[r:ACTED_WITH]->(a2:Person)-[:ACTED_IN]->(m)
WHERE m.title="Cloud Atlas" RETURN a1,a2

建议:使用标签名称可提高性能和可读性

答案 1 :(得分:1)

您可以尝试在查询中添加方向

MATCH (m)-[:ACTED_IN]-(a1)-[r]->(a2)-[:ACTED_IN]-(m)
WHERE m.title="Cloud Atlas" RETURN a1, a2

它适用于我的数据集,但是如果您在两个方向上都有重复的关系,则它将不起作用。

另一方面,重复关系似乎不是一个好习惯,您可以阅读更多here