如何在neo4j中查询确切路径并避免笛卡尔积?

时间:2019-05-02 08:15:05

标签: neo4j cypher

在一个图形中,我大约有3000个具有7000个关系的节点,但是为了演示起见,我想绘制一个子图,我确切地知道我需要哪些节点。

因此,我使用以下查询,有时会给我正确的路径(经过漫长的等待时间),有时会耗尽内存和cpu资源,直到我强制退出neo4j-browser。

MATCH p1=(:DestinationNode)-[:IS_AT]->
(:CentiDegreeNode{x: 4714, y: 843})-[:CONNECTED_TO*1]-
(:CentiDegreeNode{x: 4715, y: 843})-[:CONNECTED_TO*1]-
(:CentiDegreeNode{x: 4716, y: 843})-[:CONNECTED_TO*1]-
(:CentiDegreeNode{x: 4717, y: 843})-[:CONNECTED_TO*1]-
(:CentiDegreeNode{x: 4718, y: 843})-[:CONNECTED_TO*1]-
(:CentiDegreeNode{x: 4718, y: 844})-[:CONNECTED_TO*1]-
(:CentiDegreeNode{x: 4719, y: 844}),
p2=(:DestinationNode)-[:IS_AT]->
(:CentiDegreeNode{x: 4718, y: 839})-[:CONNECTED_TO*1]-
(:CentiDegreeNode{x: 4718, y: 840})-[:CONNECTED_TO*1]-
(:CentiDegreeNode{x: 4719, y: 840})-[:CONNECTED_TO*1]-
(:CentiDegreeNode{x: 4719, y: 841})-[:CONNECTED_TO*1]-
(:CentiDegreeNode{x: 4719, y: 842})-[:CONNECTED_TO*1]-
(:CentiDegreeNode{x: 4719, y: 843})-[:CONNECTED_TO*1]-
(:CentiDegreeNode{x: 4719, y: 844}),
p3=(:CentiDegreeNode{x: 4719, y: 844})-[:CONNECTED_TO*1]-
(:CentiDegreeNode{x: 4719, y: 845})-[:CONNECTED_TO*1]-
(:CentiDegreeNode{x: 4719, y: 846})
RETURN p1, p2, p3

我在做什么错?为了在几秒钟内执行查询,我该如何改写查询?请注意,x中的yCentiDegreeNode已建立索引。

最初我是从有向关系(-[:CONNECTED_TO]->)开始的,但这并没有更快。

非常感谢您!

2 个答案:

答案 0 :(得分:1)

当您说“ x的{​​{1}}和y被索引”时,希望您的意思是两个属性在单个索引中一起使用:{{1 }}。那会更有表现。

通过CentiDegreeNode子句分隔3条路径可能会有所帮助(这可能取决于neo4j的版本)。另外,通过沿路径收集路径,可以避免使用笛卡尔积。

:CentiDegreeNode(x, y)

答案 1 :(得分:1)

您可以使用 UNION

来重新查询以避免使用 笛卡尔积
brew install libomp

这将返回所有路径的列表,足以绘制没有笛卡尔坐标的图形

但是,如果我们需要在应用程序代码中使用此类信息,则无法区分哪种路径是哪种类型。因此,我们需要对该查询进行一些修改(在计算上比上一个昂贵)。为了通过使用 WITH 传递中间结果来实现路径分类。

match path=(:A)-[:K]->(:B) 
return path
union
match path=(:D)-[:H]->(:C) 
return path
union
match path=(:F)-[:L]->(:G}) 
return path

现在,我们可以实现路径的最佳收集和分类。

如果您使用的旧版本中没有WITH,那么您可以执行类似的操作,然后根据应用程序中的path_types进行汇总。

match path=(:A)-[:K]->(:B) 
with collect( path)  as path_list_1
match path=(:D)-[:H]->(:C) 
with path_list_1, collect( path)  as path_list_2
match path=(:F)-[:L]->(:G})
with path_list_1, path_list_2 , collect( path)  as path_list_3
return path_list_1, path_list_2 , path_list_3

干杯!