2017-02-11 88 views
0

我开始使用Neo4j,并想知道如何找到连接到另一个节点的节点,长度至多为k个边缘(朋友的朋友的朋友......最多k次)。我将以Neo4j本身的教程为例来说明(我把图形创建命令放在最下面)。Cypher阻止列举所有路径

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

该查询将返回连接到埃米尔和连接到这些节点的节点的节点。我的问题是,它似乎枚举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) 

回答

0

最大德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; 
+0

谢谢!两者都是我正在寻找的。 – steve