寻求Neo4J Cypher查询很长但(几乎)独特的路径

时间:2015-04-06 05:41:18

标签: neo4j cypher

我们有一个Neo4J数据库,代表一个具有大约100K节点和200K关系的进化过程。节点是代中的个体,边缘代表父子关系。主要目标是能够在最后一代中获取一个或多个感兴趣的节点,并探索它们的进化历史(大致上,"我们是如何到达这里的?")。

"显而易见"第一次查询找到他们的祖先并不起作用,因为在这个空间里有太多可能的祖先和路径:

match (a)-[:PARENT_OF*]->(c {is_interesting: true}) 
return distinct a;

因此我们对数据进行了预处理,以便将某些边缘标记为"特殊"这样几乎每个节点最多只有一个"特殊的"父边缘,虽然偶尔两个父边缘都标记为"特殊"。那么,我希望这个查询能够(有效地)生成(特别)"特殊的"边缘:

match (a)-[r:PARENT_OF* {special: true}]->(c {is_interesting: true}) 
return distinct a;
然而,这仍然是非常缓慢的。

这令人沮丧,因为"作为人类",逻辑很简单:从少数"有趣的"开始。节点(通常为1,从不超过几十个),并沿着几乎总是独特的特殊"追逐#34;边缘。假设节点数量非常少,有两个"特殊"父母,这应该是O(N),其中N是时代的世代数。

然而,在Neo4J中,从一个独特的"有趣的"回到25步。 每个步骤唯一的节点,需要30秒,并且一旦单个分叉(其中父母都是"特殊")作为步骤的功能,它变得更快。 28步(让我们到达第一个分叉处)需要2分钟,30分钟(那里仍然只有一个分叉)需要6分钟,我甚至没想过尝试完整的100步到达模拟的开始。

去年的一些类似工作似乎表现更好,但我们使用了各种边缘标签(例如(a)-[:SPECIAL_PARENT_OF*]->(c)以及(a)-[:PARENT_OF*]->(c)),而不是使用边缘上的数据字段。查询关系字段值是不是一个好主意?我们在这个模型中有一些不同的值附加到一个关系(一些布尔值,一些数字),我们希望/假设我们可以使用它们来有效地限制搜索,但也许情况并非如此。

非常感谢有关如何调整模型或查询的建议。

更新我应该提到,这都是Neo4J 2.1.7。我将根据Brian Underwood的建议尝试2.2尝试并报告。

2 个答案:

答案 0 :(得分:2)

我在指定路径长度限制方面有一些运气。因此,如果您知道它不会超过30个跃点,您可以尝试:

MATCH (c {is_interesting: true})
WITH c
MATCH (a)-[:PARENT_OF*1..30]->c 
RETURN DISTINCT a

此外,is_interesting属性上是否有索引?这肯定会导致缓慢。

您使用的是什么版本的Neo4j?如果您正在使用或升级到2.2.0,则可以使用新的查询分析工具:

http://neo4j.com/docs/2.2.0/how-do-i-profile-a-query.html

此外,如果您在Web控制台中使用它们,您将获得一个很好的图形树(技术术语),显示每个步骤。

答案 1 :(得分:2)

在使用Neo4J 2.2中的分析工具进行探索之后(感谢Brian Underwood的提示),很明显(目前)Neo4J没有对边缘属性进行任何预过滤,这导致了长路径的令人讨厌的组合爆炸。

例如原始查询:

match (a)-[r:PARENT_OF* {special: true}]->(c {is_interesting: true}) 
return distinct a;

找到所有ac的路径,然后消除那些边缘不是{{1}的路径}}。由于从speciala有数百万条路径,因此这是完全不可行的。

如果我在c边缘有IS_SPECIAL的地方添加PARENT_OF边缘,那么查询会变得非常快,让我可以在一个下方推回100代左右第二

此查询创建所有新边:

{special: true}

并在一秒钟内在我们的图表中添加91K关系。

然后

match (a)-[r:PARENT_OF {special: true}]->(b) 
create (a)-[:IS_SPECIAL]->(b);

需要一秒钟才能找到沿着"特殊"的112个节点。从唯一目标节点match (c {is_interesting: true}) with c match (a)-[:IS_SPECIAL*]->(c) return distinct a; 返回的路径。首先匹配c并使用c限制节点集似乎也很重要,因为Neo4J似乎也没有对节点属性进行预过滤,并且如果有多个&#34 ;有趣"目标节点事情变得慢得多。