返回一阶和二阶“朋友”的路径

时间:2018-06-08 15:04:25

标签: neo4j cypher

在我的应用程序中,Users由他们共同工作的Projects连接。我的架构看起来像(用户) - [:WORKED_ON] - >(项目),每个项目有多个用户,每个用户有多个项目。 我希望能够向某人展示他们不仅与谁合作过的网络,还有他们可能想与之联系的“朋友的朋友”。

换句话说,我想找到我所连接的用户(因为我们都连接到同一个项目,或者我们都通过我们的项目连接到同一个人)。

目视:

  • 常见项目:(me: User)-[:WORKED_ON]->(:Project)<-[:WORKED_ON]-(collaborator:User)

  • 普通合作者:(me: User)-[:WORKED_ON]->(:Project)<-[:WORKED_ON]-(common_collaborator:User)-[:WORKED_ON]->(:Project)<-[:WORKED_ON]-(collaborator:User)

所以最终结果将是一个类似的列表: Jane Doe: You and jane worked on X project John Doe: You and John have both worked with Jane

现在,我发现的唯一方法是在几个不同的查询中执行此操作。

  1. MATCH (a:User {user_id: 'theuserid'})-[:WORKED_ON*1..4]-(collaborator:User) RETURN collaborator,它为我提供了所有合作者的列表(一级和二级联系)。
  2. 以编程方式循环遍历每个协作者,并通过首先查询常见项目然后查询普通用户来查询我们如何连接到他们。 MATCH (user:User {user_id: 'theuserid'}), (other_user: User {user_id: 'otheruserid'}), (user)-[:WORKED_ON]->(common_project:Project)<-[:WORKED_ON]-(other_user) RETURN common_project MATCH (user:User {user_id: 'theuserid'}), (other_user: User {user_id: 'otheruserid'}), (user)-[:WORKED_ON*2]-(common_collaborator:User)-[:WORKED_ON*2]-(other_user) RETURN common_collaborator
  3. 当然有更好的方法吗?在此先感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

你的第一种方法看起来已经很不错了,除了我会使用2的下限作为可变长度模式:

MATCH (a:User {user_id: 'theuserid'})-[:WORKED_ON*2..4]-(collaborator:User)
RETURN collaborator;

此外,您应该确保:User(user_id)上有index

[UPDATE]

这是一个查询,它将返回包含user的行以及有关项目/协作者或common_collaborator /协作者的数据。这应该是你想要的。

MATCH p=(user:User {user_id: 'theuserid'})-[:WORKED_ON*2..4]-(col:User)
RETURN user,
  CASE WHEN LENGTH(p) = 2
    THEN {project: NODES(p)[1], collaborator: col}
    ELSE {common_collaborator: NODES(p)[2], collaborator: col} END AS data;