Neo4j通过特定节点的特定关系获得所有可达节点

时间:2018-02-09 18:56:58

标签: neo4j cypher

我想通过从节点开始的一个特定关系找出所有可到达的节点。

我有以下图表。

(User) --[LOGGED_IN]--> (Ip)
(User) --[FRIEND]--> (User)

我想通过LOGGED_IN关系找到所有可到达的用户节点。 例如

    user1 logged_in ip1
    user2 logged_in ip1
    user2 logged_in ip2
    user3 logged_in ip2
    user3 logged_in ip3
    user4 logged_in ip3
    user5 logged_in ip4
    user1 friend user5

如果我从user1开始,我想找到user1,user2,user3,user4。 我想忽略FRIEND关系。

我知道如果我只有[:LOGGED_IN]关系我可以做下面的密码。但我也有FRIEND关系,这也会给我通过[:FRIEND]链接的用户

MATCH (u:User)-[*]->(connected:User)
WHERE u.user_id = <user1_id>
RETURN connected

2 个答案:

答案 0 :(得分:1)

这应该有效(使用<user1_id>的适当值):

MATCH (u:User)-[:logged_in*0..]-(connected:User)
WHERE u.user_id = <user1_id>
RETURN DISTINCT connected;

(u:User)-[:logged_in*0..]-(connected:User)模式:

  • 要求所有匹配关系的类型为logged_in
  • 为可变长度路径模式指定0的下限,允许将u节点本身分配给connected
  • 未指定loggeded_in关系的方向,以允许从Ip个节点到User个节点的遍历(反之亦然)。

DISTINCT关键字用于消除重复结果。

此查询将始终返回u节点(如果存在),因为节点可以从其自身轻易到达。

[增订]

如果你有足够的数据,那么可变长度路径模式必须指定一个合理的上限(例如[:logged_in*0..5]),以避免内存不足或查询需要永远完成。

答案 1 :(得分:1)

如果您的节点是深度互连的,那么单独的密码可能无法为您解决问题,因为具有可变长度路径的密码中的MATCH操作都是为了找到适合该模式的所有可能路径,这很快就会让您陷入困境可能的路径数量通过屋顶。当您只关心不同的连接节点时,这不太合适。

如果您有权访问APOC程序,则有一些path expander procedures针对查找连接的节点进行了优化。安装和配置APOC后,尝试一下:

MATCH (u:User)
WHERE u.user_id = <user1_id>
CALL apoc.path.subgraphNodes(u, {relationshipFilter:'LOGGED_IN', labelFilter:'>User', filterStartNode:true}) YIELD node as connected
RETURN connected;