【问题标题】:Neo4j all reachable nodes thru a specific relationship from a specific nodeNeo4j 通过特定节点的特定关系所有可达节点
【发布时间】:2018-02-09 18:56:58
【问题描述】:

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

我有下面的图表。

(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

【问题讨论】:

    标签: neo4j cypher


    【解决方案1】:

    这应该有效(&lt;user1_id&gt; 具有适当的值):

    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])以避免内存不足或让查询永远完成。

    【讨论】:

    • 问题是我有数百万个节点......这会运行得太慢,有时甚至会导致我的 neo4j 崩溃。我正在做一些像这样的愚蠢的事情。这速度很快,但并不优雅,我找不到所有可访问的节点。我只能在我指定的深度内找到节点。
      MATCH (u: User)-[:LOGGED_IN]-&gt;(ip1: Ip) WITH ip1 MATCH (tier1: User)-[:LOGGED_IN]-&gt;(ip1: Ip) WITH tier1 MATCH (tier1)-[:LOGGED_IN]-&gt;(ip2: Ip) WITH ip2 MATCH (tier2: User)-[:LOGGED_IN]-&gt;(ip2: Ip) RETURN ip2
    • 我已经更新了我的答案,以展示如何通过指定可变长度路径模式的上限来方便地执行等效操作。不过,这仍然不会为您提供所有可访问的节点。
    • 我猜这是一个指数计算....[:logged_in*0..4] 很快,花了 7 秒。 [:logged_in*0..6] 导致我的 CPU 过热...lol
    【解决方案2】:

    如果您的节点是深度互连的,那么单独使用 cypher 可能不适合您,因为 cypher 中具有可变长度路径的 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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-29
      • 1970-01-01
      • 2023-01-22
      • 1970-01-01
      • 2022-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多