Neo4j 具有权重的复杂查询的密码查询超时

Neo4j 具有权重的复杂查询的密码查询超时,neo4j,cypher,Neo4j,Cypher,我有一个相当简单的图表。它只有大约100个节点和400个关系。我正在尝试运行各种各样的密码查询,根据某些关系的存在对结果进行排序。然而,即使使用小型数据库,这些查询也会超时。有人能确定我的查询中会导致超时的问题吗 下面的查询搜索各种模式。如果模式存在,它会对关系应用权重。最后,它将权重合并并对结果进行排序,以使权重最高的节点(最重要的关系)获得优先权 START node=node(1) MATCH (node)-[a?:REQUIRES]-(thing0)-[?:RELATED]-(stu

我有一个相当简单的图表。它只有大约100个节点和400个关系。我正在尝试运行各种各样的密码查询,根据某些关系的存在对结果进行排序。然而,即使使用小型数据库,这些查询也会超时。有人能确定我的查询中会导致超时的问题吗

下面的查询搜索各种模式。如果模式存在,它会对关系应用权重。最后,它将权重合并并对结果进行排序,以使权重最高的节点(最重要的关系)获得优先权

START node=node(1) 
MATCH  (node)-[a?:REQUIRES]-(thing0)-[?:RELATED]-(stuff) 
,(node)-[b?:REQUIRES]-(thing1)-[:RELATED]-(system1)-[:COMPOSITION]-(something1)-[?:VERSION]-(stuff) 
,(node)-[c?:REQUIRES]-(thing2)-[:RELATED]-(something2)-[?:VERSION]-(stuff) 
,(node)-[d?:REQUIRES]-(thing3)-[:REQUIRES]-(project1)-[:REQUIRES]-(thing6)-[?:RELATED]-(stuff) 
,(node)-[e?:REQUIRES]-(thing4)-[:DESCRIBES]-(part)-[:DESCRIBES]-(thing5)-[?:RELATED]-(stuff) 
WITH stuff
, count(distinct a)*.15 as shareA
, count(distinct b)*.35 as shareB
, count(distinct c)*.25 as shareC
, count(distinct d)*.10 as shareD
, count(distinct e)*.15 as shareE 
WHERE has(stuff.__type__) 
AND stuff.__type__='full.namespace.to.stuff' 
SET stuff.weight = shareA + shareB + shareC + shareD + shareE 
RETURN DISTINCT stuff 
ORDER BY stuff.weight DESC 

我认为您需要去掉optionals,并在一个批处理请求或事务中的几个cypher语句中执行此操作

START stuff=node(*) 
WHERE has(stuff.__type__) AND stuff.__type__='full.namespace.to.stuff' 
SET stuff.weight = 0.0;

START node=node(1) 
MATCH  (node)-[a:REQUIRES]-(thing)-[:RELATED]-(stuff) 
WHERE has(stuff.__type__) AND stuff.__type__='full.namespace.to.stuff' 
SET stuff.weight = stuff.weight + COUNT(DISTINCT a)*.15;

START node=node(1) 
MATCH (node)-[b:REQUIRES]-(thing)-[:RELATED]-(system1)-[:COMPOSITION]-(something1)-[:VERSION]-(stuff) 
WHERE has(stuff.__type__) AND stuff.__type__='full.namespace.to.stuff' 
SET stuff.weight = stuff.weight + COUNT(DISTINCT b)*.35

START node=node(1) 
MATCH (node)-[c:REQUIRES]-(thing2)-[:RELATED]-(something2)-[:VERSION]-(stuff) 
WHERE has(stuff.__type__) AND stuff.__type__='full.namespace.to.stuff' 
SET stuff.weight = stuff.weight + COUNT(DISTINCT c)*.25

START node=node(1) 
MATCH (node)-[d:REQUIRES]-(thing3)-[:REQUIRES]-(project1)-[:REQUIRES]-(thing6)-[:RELATED]-(stuff) 
WHERE has(stuff.__type__) AND stuff.__type__='full.namespace.to.stuff' 
SET stuff.weight = stuff.weight + COUNT(DISTINCT d)*.10

START node=node(1) 
MATCH (node)-[e:REQUIRES]-(thing4)-[:DESCRIBES]-(part)-[:DESCRIBES]-(thing5)-[:RELATED]-(stuff) 
WHERE has(stuff.__type__) AND stuff.__type__='full.namespace.to.stuff' 
SET stuff.weight = stuff.weight + COUNT(DISTINCT e)*.15

START stuff=node(*) 
WHERE has(stuff.__type__) AND stuff.__type__='full.namespace.to.stuff' 
RETURN DISTINCT stuff 
ORDER BY stuff.weight DESC 

你可以用“with”链接所有内容,但我认为这会让它变得非常混乱。

我认为你应该去掉可选项,在一个批处理请求或事务中的几个密码语句中完成这项操作

START stuff=node(*) 
WHERE has(stuff.__type__) AND stuff.__type__='full.namespace.to.stuff' 
SET stuff.weight = 0.0;

START node=node(1) 
MATCH  (node)-[a:REQUIRES]-(thing)-[:RELATED]-(stuff) 
WHERE has(stuff.__type__) AND stuff.__type__='full.namespace.to.stuff' 
SET stuff.weight = stuff.weight + COUNT(DISTINCT a)*.15;

START node=node(1) 
MATCH (node)-[b:REQUIRES]-(thing)-[:RELATED]-(system1)-[:COMPOSITION]-(something1)-[:VERSION]-(stuff) 
WHERE has(stuff.__type__) AND stuff.__type__='full.namespace.to.stuff' 
SET stuff.weight = stuff.weight + COUNT(DISTINCT b)*.35

START node=node(1) 
MATCH (node)-[c:REQUIRES]-(thing2)-[:RELATED]-(something2)-[:VERSION]-(stuff) 
WHERE has(stuff.__type__) AND stuff.__type__='full.namespace.to.stuff' 
SET stuff.weight = stuff.weight + COUNT(DISTINCT c)*.25

START node=node(1) 
MATCH (node)-[d:REQUIRES]-(thing3)-[:REQUIRES]-(project1)-[:REQUIRES]-(thing6)-[:RELATED]-(stuff) 
WHERE has(stuff.__type__) AND stuff.__type__='full.namespace.to.stuff' 
SET stuff.weight = stuff.weight + COUNT(DISTINCT d)*.10

START node=node(1) 
MATCH (node)-[e:REQUIRES]-(thing4)-[:DESCRIBES]-(part)-[:DESCRIBES]-(thing5)-[:RELATED]-(stuff) 
WHERE has(stuff.__type__) AND stuff.__type__='full.namespace.to.stuff' 
SET stuff.weight = stuff.weight + COUNT(DISTINCT e)*.15

START stuff=node(*) 
WHERE has(stuff.__type__) AND stuff.__type__='full.namespace.to.stuff' 
RETURN DISTINCT stuff 
ORDER BY stuff.weight DESC 

你可以用“with”来连用,但我认为这会让事情变得相当混乱。

我没有时间给出正确的答案,但可选的关系匹配者往往是缓慢的原因。您可以尝试使用
将其拆分,这样您就不需要使用可选关系(如果可能的话)。你有没有做过一个
档案
来看看什么会回来?我是Neo4j的新手。我可以解释“完成概要文件”是什么意思吗?另外,我不确定是否可以使用“WITH”重写查询。我正在检查的每个模式实际上都是可选的。我相信WITH会将结果集限制为只包含匹配所有模式的节点。将
profile
附加到密码的开头,它将返回一个执行计划。尝试使用*0..1可变长度模式,而不是使用可选关系。对于PatternMatch,配置文件显示_rows=49880,_db_hits=193791134,即使只有118个节点和432个关系。用可变长度模式替换可选关系没有任何效果(或者是负面效果,因为它已经运行了20分钟,还没有返回结果)。我没有时间给出正确的答案,但可选关系匹配器通常是导致速度缓慢的原因。您可以尝试使用
将其拆分,这样您就不需要使用可选关系(如果可能的话)。你有没有做过一个
档案
来看看什么会回来?我是Neo4j的新手。我可以解释“完成概要文件”是什么意思吗?另外,我不确定是否可以使用“WITH”重写查询。我正在检查的每个模式实际上都是可选的。我相信WITH会将结果集限制为只包含匹配所有模式的节点。将
profile
附加到密码的开头,它将返回一个执行计划。尝试使用*0..1可变长度模式,而不是使用可选关系。对于PatternMatch,配置文件显示_rows=49880,_db_hits=193791134,即使只有118个节点和432个关系。用可变长度模式替换可选关系没有任何影响(或者是负面影响,因为它已经运行了20分钟,尚未返回结果)。您的解决方案应该可以工作。但是,我计划更改加权方法,这样就不会将权重保存到节点。如果多个用户正在运行类似的查询,则可能会导致并发问题。我必须承认,我很惊讶cypher不能处理这种类型的查询。将这些查询与“with”链接也会导致超时。我不太愿意把它们全部分开,因为我开发了几十个这样的查询,每个查询都是并行运行的。如上所述,将权重保存到节点会导致问题。这些查询在一个小图中运行良好。如果图形数据库不能处理复杂的关系,我真的看不到它的价值。关系数据库可以更有效地处理这一问题,问题是您的可选关系会破坏查询。你能在某个地方发布一个压缩的graph.db文件夹以便我们可以使用它吗?很遗憾,我不能发布数据库。但我能够用一个小到26个节点的图来复制这个问题。目前,我创建了更多的通用查询。我感谢大家在这个问题上的帮助。你的解决方案应该有效。但是,我计划更改加权方法,这样就不会将权重保存到节点。如果多个用户正在运行类似的查询,则可能会导致并发问题。我必须承认,我很惊讶cypher不能处理这种类型的查询。将这些查询与“with”链接也会导致超时。我不太愿意把它们全部分开,因为我开发了几十个这样的查询,每个查询都是并行运行的。如上所述,将权重保存到节点会导致问题。这些查询在一个小图中运行良好。如果图形数据库不能处理复杂的关系,我真的看不到它的价值。关系数据库可以更有效地处理这一问题,问题是您的可选关系会破坏查询。你能在某个地方发布一个压缩的graph.db文件夹以便我们可以使用它吗?很遗憾,我不能发布数据库。但我能够用一个小到26个节点的图来复制这个问题。目前,我创建了更多的通用查询。我感谢大家在这个问题上的帮助。