【问题标题】:Cypher prevent enumerating all pathsCypher 防止枚举所有路径
【发布时间】:2017-02-11 21:56:06
【问题描述】:

我开始使用 Neo4j 并想知道如何找到连接到另一个节点的节点,其长度最多为 k 条边(朋友的朋友的朋友的朋友的朋友的朋友的朋友的朋友......最多 k 次)。我将用 Neo4j 本身的教程中的示例进行说明(我将图形创建命令放在底部)。

match (e {name:"Emil"})-[*1..2]-(p)
return DISTINCT e, p;

此查询将返回连接到 Emil 的节点以及连接到这些节点的节点。我的问题是,这似乎从 Emil 枚举了长度为 1-2 的每条路径,尽管我不关心枚举所有路径。从查询中,很明显我只关心在那个距离连接到 Emil 的节点,并且枚举所有可能的路径是实现该查询的糟糕方法。随着复杂性变得压倒性,这在大型密集图中是一个问题。

去掉 DISTINCT 会有 8 条记录,这是来自 Emil 的唯一 1-2 长度路径的数量。根据我对较大图的测试,似乎 DISTINCT 是一个不会影响查询运行时间的后处理步骤,尽管它会消除冗余输出。对吗?

我的主要问题是,有没有办法针对这个问题形成一个 Cypher 查询,这样我就不会遍历所有唯一路径并且可以降低复杂性?如果我在某个地方也有误解,请告诉我。

---- 创建图表的命令 -----

CREATE (ee:Person { name: "Emil", from: "Sweden", klout: 99 })
CREATE (js:Person { name: "Johan", from: "Sweden", learn: "surfing" }),
(ir:Person { name: "Ian", from: "England", title: "author" }),
(rvb:Person { name: "Rik", from: "Belgium", pet: "Orval" }),
(ally:Person { name: "Allison", from: "California", hobby: "surfing" }),
(ee)-[:KNOWS {since: 2001}]->(js),(ee)-[:KNOWS {rating: 5}]->(ir),
(js)-[:KNOWS]->(ir),(js)-[:KNOWS]->(rvb),
(ir)-[:KNOWS]->(js),(ir)-[:KNOWS]->(ally),
(rvb)-[:KNOWS]->(ally)

【问题讨论】:

    标签: neo4j cypher


    【解决方案1】:

    Neo 的 Max De Marzi 写了一篇关于此类查询的精彩 blog post,因此查询规划器将在未来版本中检测和优化唯一感兴趣的不同节点而非路径的可变长度匹配,可能是 3.2。

    与此同时,当您提供“NODE_GLOBAL”作为唯一性参数时,APOC 程序在其apoc.path.expandConfig() 调用中有一个解决方案。

    这将确保在路径扩展期间找到的节点仅被访问一次,因此您不应看到多个路径到同一个节点。

    match (e {name:"Emil"})
    call apoc.path.expandConfig(e, {maxLevel:2, uniqueness:'NODE_GLOBAL'}) yield path
    WITH e, last(nodes(path)) as subgraph
    where e <> subgraph
    return  e, subgraph;
    

    【讨论】:

    • 谢谢!两者都正是我想要的。
    猜你喜欢
    • 2020-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-21
    • 1970-01-01
    • 2018-08-29
    • 1970-01-01
    相关资源
    最近更新 更多