连接两组节点的高效密码查询匹配子图

时间:2015-01-14 12:42:17

标签: performance neo4j cypher subgraph

我的问题如下。我在Neo4j中有一个小但密集的网络(~280个节点,~3600个关系)。只有一种类型的节点和一种类型的边缘(即每种节点都有一个标签)。现在,我想指定两个不同的节点组,由“group”属性的值给出,并匹配包含连接两个组的特定长度的所有路径的子图。另外我想对关系添加约束。所以,目前我有这个:

MATCH (n1) WHERE n1.group={group1} 
MATCH (n2) WHERE n2.group={group2}
MATCH p=(n1)-[r*1..3]-(n2) 
WHERE ALL(c IN r WHERE c.weight > {w}) 
AND ALL(n in NODES(p) WHERE 1=length(filter(m in NODES(p) WHERE m=n))) 
WITH DISTINCT r AS dr, NODES(p) AS ns 
UNWIND dr AS udr UNWIND ns AS uns 
RETURN COLLECT(DISTINCT udr), COLLECT(DISTINCT uns)

实现我想要的但在某些情况下似乎太慢了。这里WHERE语句过滤掉权重属性低于阈值的关系以及包含循环的路径。

最后三行与所需的输出格式有关。给定匹配的子图(路径),我想要一个列表中的所有唯一关系,以及另一个列表中的所有唯一节点(用于与d3.js一起显示)。我发现这样做的唯一方法是UNWIND所有元素,然后将它们收集为DISTINCT。

另请注意,组属性和权重限制作为查询参数传递。

现在,有没有办法更快地达到相同的效果?例如,路径长度为3,查询在我的本地机器上大约需要5-10秒(取决于所选节点组的连通性),并返回约50个节点和几百个关系的顺序。这似乎达到了可接受的性能。然而,长度为4的路径已经过时(几分钟或永不返回)。

奖金问题:有没有办法将路径长度的上限指定为参数?或者,不同的限制是否意味着完全不同的查询计划?

1 个答案:

答案 0 :(得分:0)

这可能根本不起作用,但它可能会给你一些东西。我尝试改变一些可能有效或无效的事情。

MATCH (n1) WHERE n1.group={group1} 
MATCH (n2) WHERE n2.group={group2}
MATCH p=(n1)-[r*1..3]-(n2) 
WHERE r.weight > {w}
WITH n1, NODES(p) AS ns, n2, DISTINCT r AS dr
WHERE length(ns) = 1
UNWIND dr AS udr UNWIND ns AS uns 
RETURN COLLECT(DISTINCT udr), COLLECT(DISTINCT uns)