Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在neo4j图形中从路径中删除循环的更好方法_Neo4j_Cypher - Fatal编程技术网

在neo4j图形中从路径中删除循环的更好方法

在neo4j图形中从路径中删除循环的更好方法,neo4j,cypher,Neo4j,Cypher,我使用的是neo4j图形数据库版本2.1.7。有关数据的简要详细信息: 200万个节点有6种不同类型的节点,500万个关系只有5种不同类型的关系,大部分是连通图,但包含一些孤立的子图 在解析路径时,我在路径中获得循环。为了限制这一点,我使用了下面共享的解决方案: 以下是我使用的查询: MATCH (n:nodeA{key:905728}) MATCH path = n-[:rel1|rel2|rel3|rel4*0..]->(c:nodeA)-[:rel5*0..1]->(b:n

我使用的是neo4j图形数据库版本2.1.7。有关数据的简要详细信息: 200万个节点有6种不同类型的节点,500万个关系只有5种不同类型的关系,大部分是连通图,但包含一些孤立的子图

在解析路径时,我在路径中获得循环。为了限制这一点,我使用了下面共享的解决方案:

以下是我使用的查询:

MATCH (n:nodeA{key:905728}) 
MATCH path = n-[:rel1|rel2|rel3|rel4*0..]->(c:nodeA)-[:rel5*0..1]->(b:nodeA) 
WHERE ALL(a in nodes(path) where 1=length (filter (m in nodes(path) where m=a))) 
and (length(EXTRACT (p in NODES(path)| p.key)) > 1) 
and ((exists ((c)-[:rel5]->(b)) and (not exists((b)-[:rel1|rel2|rel3|rel4]->(:nodeA)) OR ANY (x in nodes(path) where (b)-[]->(x))))
    OR (not exists ((c)-[:rel5]->()) and (not exists ((c)-[:rel1|rel2|rel3|rel4]->(:nodeA)) OR ANY (x in nodes(path) where (c)-[]->(x))))) 
RETURN distinct EXTRACT (rp in Rels(path)| type(rp)), EXTRACT (p in NODES(path)| p.key);

上面的查询解决了我的需求,但不符合成本效益,如果为巨大的子图运行,则会继续运行。我已经使用“Profile”命令从一开始就提高了查询性能。但是,现在却停留在这一点上。性能有所提高,但与我对neo4j的期望不同:(

我不知道我有什么解决方案,但我有一些建议。有些可能会加快速度,有些可能只是让查询更容易阅读

首先,与其将
存在((c)-[:rel5]->(b))
放在
中,我相信您可以将其放在
匹配中,如下所示:

MATCH path = n-[:rel1|rel2|rel3|rel4*0..]->(c:nodeA)-[:rel5*0..1]->(b:nodeA), (c)-[:rel5]->(b)
我认为您不需要
exists
关键字。我认为您可以说,例如,
(不是(b)-[:rel1 | rel2 | rel3 | rel4]->(:nodeA))

我还建议考虑潜在的性能改进

关于变量路径的几点注意事项:在
*0..
中,
0
意味着您可能正在寻找一个自我引用。这可能是您想要的,也可能不是您想要的。另外,保持变量路径的开放性通常会导致性能问题(我认为您已经看到)。如果您可以限制它,这可能会有所帮助

此外,如果您升级到2.2.1,2.2.x行会有许多内置的性能改进,但您也会在控制台中看到可视化的
PROFILE
ing和一个新的
EXPLAIN
命令,该命令会在运行查询后对其进行配置并告诉您查询的实际性能


一个要考虑的事情是,我不认为你正在击中NeN4J的性能边界,但是,也许,你可能会碰到CyfER的一些边界。如果是这样,我建议你用java API来查询No4J提供的更好的性能和更多的控制。您正在使用与JVM兼容的语言,或者通过编写一个允许您使用java进行自己的查询但从服务器提供一个自定义REST API的脚本,对我的查询进行了一些调整,正如Brian所建议的那样。并且发现查询响应时间有了改进。现在,与我的原始查询和在查询执行期间,与我之前共享的查询相比,当前查询的数据库命中率减少了近60%。PFB更新的查询:

MATCH (n:nodeA{key:905728}) 
MATCH path = n-[:rel1|rel2|rel3|rel4*1..]->(c:nodeA)-[:rel5*0..1]->(b:nodeA) 
WHERE ALL(a in nodes(path) where 1=length (filter (m in nodes(path) where m=a))) 
and (length(path) > 0) 
and ((exists ((c)-[:rel5]->(b)) and (not ((c)-[:rel1|rel2|rel3|rel4]->()) OR ANY (x in nodes(path) where (c)-[]->(x))))
    OR (not exists ((c)-[:rel5]->()) and (not ((c)-[:rel1|rel2|rel3|rel4]->()) OR ANY (x in nodes(path) where (c)-[]->(x))))) 
RETURN distinct EXTRACT (rp in Rels(path)| type(rp)), EXTRACT (p in NODES(path)| p.key);
当将路径从*1..限制到*1..15时,观察到了显著的改进。此外,从查询中删除了一个过滤器,这也需要更长的时间。 但是,当在关系深度超过18-20的节点上查询时,查询响应时间会增加

我建议经常使用profile命令来查找查询中的难点。这将帮助您更快地解决问题。
谢谢Brian。

谢谢@Brian的回复。我一定会处理您分享的建议并分享一个更新。在*0..上,您是对的,我已经更新了它*1…我发现自己不够幸运,无法保持cap的路径,并且必须保持它的开放性。