与Cypher的多次匹配非常慢

时间:2018-01-09 10:45:47

标签: neo4j cypher

我昨天开始使用Cypher并遇到了问题。我的层次结构如下:

ReleaseCycle->线 - > ProductSet

所以“ReleaseCycle”是最少的元素,在最顶层的层次结构树中。 “ReleaseCycle”中的子项为“Line”,“Line”中的子项为“ProductSet”,其中包含最多的数据。所有这些都与“releaseTask”有关,我想返回所有releaseTask。

此刻我的密码调用如下:

MATCH (a1:Line)<-[:contains]-(b1:ReleaseCycle{id:'xyz'})<-[c1:releaseTask]-(d1:Task)      
MATCH (a2:ProductSet)<-[:contains]-(b2:Line{id: a1.id})<-[c2:releaseTask]-(d2:Task)  
MATCH (b3:ProductSet{id: a2.id})<-[c3:releaseTask]-(d3:Task)

RETURN COLLECT(DISTINCT {a:"cycle", task: d1, contributor: c1.contributor}),                             
COLLECT(DISTINCT {a:"Line", task: d2, contributor: c2.contributor}),
COLLECT(DISTINCT {a:"ps", task: d3, contributor: c3.contributor})

问题是响应需要5秒钟,似乎缺少条目。我的结果只有800但它应该是3000 ...也许是因为“Distinct”和Collect()但是如果我不使用它们,我会因为查询耗时太长而得到超时。

感谢您的帮助

1 个答案:

答案 0 :(得分:0)

如果您查询查询,您将看到在查询执行时生成的记录/行数可能会很多。 Cypher操作按记录/行执行,因此您执行的工作量远远超过需要的工作量。

具有聚合的密钥是尽可能早地收集(在有意义的地方),这将反过来减少基数(查询中的记录/行),这意味着需要执行的操作更少,同时更少的冗余操作节点/数据。

在您的情况下,按步骤执行此操作是有意义的,并使用pattern comprehension作为匹配模式和收集结果的简写。

您还可以在整个查询中重复使用变量,而不必重新匹配已有的节点(尽管WITH允许您重新定义变量在范围内)。

尝试这一个,如果它给出了良好的结果,请查看它以区别:

MATCH (release:ReleaseCycle{id:'xyz'})
WITH release, [(release)<-[rel:releaseTask]-(task:Task) | 
 {a:"cycle", task:task, contributor:rel.contributor}] as cycleTasks   
MATCH (line:Line)<-[:contains]-(release)
WITH cycleTasks, line, [(line)<-[rel:releaseTask]-(task:Task) | 
 {a:"Line", task:task, contributor:rel.contributor}] as lineTasks
MATCH (prod:ProductSet)<-[:contains]-(line)
WITH cycleTasks, lineTasks, [(prod)<-[rel:releaseTask]-(task:Task) | 
 {a:"ps", task:task, contributor:rel.contributor}] as psTasks
RETURN cycleTasks, lineTasks, psTasks

此外,请确保在查找起始节点/节点时计划使用的标签/属性组合上有索引。