【问题标题】:Getting all relationships among neighbors of a node获取节点邻居之间的所有关系
【发布时间】:2013-01-18 17:44:27
【问题描述】:

我有一个节点(推特用户)和有向边(跟随)的嵌入式图形数据库。

我正在尝试获取指定用户(节点 U)之后的用户(集合 A)之间的所有关系。还有A中的节点与指定节点U之间的关系。

我的查询:

START u=node:user_id(user_id={id_of_U})
MATCH p = u-->following, p2= following-[?]->u, p3 = following-[?]->()<--u
RETURN distinct rels(p),rels(p2),rels(p3) 

这个查询给了我我期望的结果,但问题是,当指定的用户关注太多用户时,它需要很长时间。

我尝试了很多查询,上面的查询是迄今为止最好的查询。然而,我确信有更有效的方法可以做到这一点,因为当我通过遍历“A”中的所有用户来获取这些关系时,获取每个用户的所有关系(Direction.BOTH),然后过滤与“A”的关系(删除具有不属于“A”的开始或结束节点的关系),跟踪 500 人的用户只需 8 秒,而密码查询甚至不会在不炸毁我的堆的情况下失败...

【问题讨论】:

    标签: performance neo4j cypher


    【解决方案1】:

    p = u--&gt;following 开始并不是最优的,因为它需要所有相关的节点,然后你会尝试过滤这些节点。我建议选择更少的节点,然后稍微扩展一下这个集合:

    START u=node:user_id(user_id={id_of_U})
    MATCH u-[:FOLLOWS]->following
    WITH u,following
    MATCH u-[r]-following
    RETURN distinct r;
    

    这将为您提供 setA 中的节点之间的所有关系,这些节点也由节点 U 跟踪。

    如果您的图表中没有 FOLLOW 关系 - 您应该有,否则您的图表设计不是最优的。我注意到您没有在查询中使用任何特定的 rel 类型 - 当且仅当您的数据中只有 1 个关系类型时,这可能是最佳的。据我了解您的问题,您有超过 1 种 rel 类型。

    编辑:

    START u=node:user_id(user_id={id_of_U})
    MATCH u-[]-following
    WITH u, following
    MATCH u-[r]-again, again-[r2]-following
    RETURN r, r2
    

    【讨论】:

    • 您的查询只给出ufollowing 之间的关系...我还想要得到following[m]-following[n] 之间的所有关系following[m] 和@987654329 @ 是集合 A 的元素。这是我无法处理的棘手部分。 (顺便说一句,我的图表有一种关系,FOLLOWS)
    • thx,我已经更新了我的答案,关键是将 setA 两次匹配到两个不同的变量中,然后匹配这些变量之间的 rels。如果这仍然会达到你的堆限制,恐怕唯一的方法是使用 gremlin 并严格定义算法。
    • 实际上您建议的查询导致了堆错误,但再添加一个WITH 解决了该问题。 START u=node:user_id(user_id='109537107') MATCH u-[]-&gt;following WITH u, following MATCH u-[r]-&gt;again WITH following,again,r MATCH again-[r3]-&gt;following RETURN r,r3 然而,我做了另一个实现,首先我得到u 跟随的所有节点的ID。然后将它们作为START u=node({nodeIdList}), u2= node({nodeIdList2}) MATCH u-[r]-&gt;u2, u2-[r2]-&gt;u RETURN distinct r,r2 之类的参数传递两次,这提供了最快的解决方案。也许我们应该等待新版本的 neo4j...
    • 但是您对使用 WITH 的建议很重要,这让我更加了解了 cypher 的工作方式。多谢。如果几天后没有其他答案可以做得更好,我会接受您的答案作为解决问题的答案。我只想等待并确保我们没有更好的选择。
    • 很好地升级了查询。有时,neo4j 无法以有用的方式解决某些问题 - 例如,当存在超级节点或查询中匹配的元素数量过多时 - 这是一个计算问题,而不是软件问题,因此我恐怕neo4j 永远不会在这方面变得更好。在这种情况下,我建议使用 gremlin 构建自己的图形算法,或者使用完全不同的技术,可能是 apache hadoop 和 minhash 在服务器集群上。
    【解决方案2】:

    你可以试试这个吗?

    start u=node:user_id(user_id={id_of_U})
    MATCH u-[r]->following
    with u, r, following
    match following-[r2?]->u, following-[r3?]->()<-[r4]-u
    RETURN distinct r, r2, r3, r4
    

    另外,您使用的是最新的 1.9 吗?

    【讨论】:

    • 我使用的是 1.8.1,但现在升级到 1.9 并尝试了您的查询,但没有任何改变......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-22
    相关资源
    最近更新 更多