如何解决为什么适度的MATCH和CREATE查询在Neo4j浏览器中旋转? 创建节点花费的时间比预期的长语法首选项?关系创建旋转并超时/崩溃
概述
我正在使用Neo4j桌面浏览器在网站内创建页面关系图。我确信csv加载使此操作更有效,但似乎该查询不会像它那样引起太多问题。
- 创建节点所需的时间比预期的长(语法首选项?)
- 关系创建旋转并超时/崩溃
。 。
问题1
创建节点花费的时间比预期的长(语法首选项?)
我正在创建大约6,500个非常基本的节点(每个节点中包含1条信息):
create (a1:link {description:"www.samplelink.com/example1"})
我正在用Excel构建查询并将其复制粘贴到neo4j浏览器中。我可以用以下两种方式之一构建它:
create (a1:link {description:"www.samplelink.com/example1"})
create (a2:link {description:"www.samplelink.com/example2"})
create (a3:link {description:"www.samplelink.com/example3"})
...x6,000
OR
create (a1:link {description:"www.samplelink.com/example1"}),(a2:link {description:"www.samplelink.com/example2"}),(a3:link {description:"www.samplelink.com/example3"}),...x6,000
问:是否有首选语法?每个人都有什么优势? 6,500个节点(尤其是没有大量信息的基本节点),似乎并没有大幅提高性能。查询需要5分钟到15分钟以上的任何时间,程序声明的实际运行时间为7,000毫秒或47,000毫秒。但是实际的浏览器旋转所需的时间要比规定的最终运行时间长得多。
。 。
问题2
关系创建旋转并超时/崩溃
我构造(我所解释的)非常简单的match子句来分配昵称。字符串匹配是文字的(没有正则表达式),没有图形遍历,并且关系很简单。
match (a1:link {description:"www.samplelink.com/example1"})
match (a2:link {description:"www.samplelink.com/example2"})
match (a3:link {description:"www.samplelink.com/example3"})
...x6,000
create (a1)-[:REF]->(a3)
create (a1)-[:REF]->(a47)
create (a5832)-[:REF]->(a9)
...x5,000
此查询运行2个小时以上,然后崩溃/超时。
问:再次从语法角度讲,我是否正在做一些难以置信的内存消耗工作?应该用稍微不同的方式写吗?一个用逗号分隔的短语?为关系创建一个短语吗?
。 。
我的阅读材料
1。我考虑了这篇关于基数的文章:
https://neo4j.com/developer/kb/understanding-cypher-cardinality/
似乎我是在无意间创建了一个巨大的关系交叉产品,而不是每个预期的关系...?我也不知道MATCH语法是否对neo4j输出“行”,将那些行保存在内存中,然后对每一行进行所需的操作有什么有趣之处。
在一个MATCH短语中进行MATCH效率更高吗?与创建关系相同。
MATCH (a1:link {desc:"alpha"}),(a2:link {desc:"beta"}),(a3:link {desc:"gamma"})
2。索引
我看到很多地方人们对其他旋转查询帖子进行评论,以创建索引。
我确实尝试创建索引CREATE INDEX ON :link(description)
,但是由于SQL背景的原因,我不知道这将如何从根本上加速仅使用6,500个文字字符串匹配的查询。
3。相似的挂起问题
批准的答案,第三点,建议将其分解为较小的事务,每个MATCH / CREATE为100。我想我能做到吗?在Excel中似乎要摆弄很多东西,以确保我的MATCH子句包括CREATE部分的正确节点。似乎neo4j应该能够处理内存中的6,500个节点和5,000个基本关系...我在这里没有做任何高级的事情。
更新
我现在以“ MATCH节点,节点,节点”格式而不是“ MATCH节点MATCH节点MATCH节点”格式重新运行查询。我只有1条CREATE语句,这是2个节点之间的随机关系。这个具有单个CREATE子句的(显然是很大的)MATCH子句花费了15分钟以上。因此,我认为这是将所有节点都保留在内存中的问题。
查询以错误结尾:“ Neo.TransientError.General.StackOverFlowError-堆栈大小不足以执行当前任务。这通常被认为是数据库错误,因此请联系Neo4j支持。您可以尝试增加堆栈大小:例如,要将堆栈大小设置为2M,请在neo4j配置中添加“ dbms.jvm.additional = -Xss2M”(通常在“ conf / neo4j.conf”中;如果使用的是Neo4j Desktop,则找到通过用户界面),或者如果您正在运行嵌入式安装,只需添加-Xss2M作为命令行标志即可。”
我将其构建为极其基本的MATCH node1 MATCH node2 CREATE(node1)-[:REL]->(node2);并将这些查询串在一起。每个小型查询都连续运行,但是在我的Neo4j浏览器中,每个查询实际上需要2秒的时间(经过30秒的预热后才能处理/编译初始查询)。 300个查询将以这种速度花费10分钟。我有5,000份陈述要通过。当人们创建具有数千/百万/十亿个节点的图时,必须有一种更有效的方法。就像“不使用Neo4j浏览器”一样简单吗?并使用csv加载?
解决方法
问题1 :您应将parameter中所有description
值的列表传递给查询。而且查询仅可以使用UNWIND
从该列表中获取元素。该查询将非常小,并且执行速度更快(并避免了Cypher注入攻击)。
例如(如果列表是通过descriptions
参数传递的):
UNWIND $descriptions AS desc
CREATE (a1:link {description: desc})
您可能希望将非常大的列表分成较小的块,但是6500并不是很大。
问题2 :您可以使用@TomažBratanič的方法,也可以使用与我针对问题1的方法类似的方法。也就是说,您可以传递对的列表您查询的description
个值中的>。
例如,如果descriptionPairs
参数的每个元素都是2个description
值的列表:
UNWIND $descriptionPairs AS descPair
MATCH (a1:link {description: descPair[0]})
MATCH (a2:link {description: descPair[1]})
CREATE (a1)-[:REF]->(a2)
而且,要使该查询真正快速,您还应该在:link(description)
上创建一个index。
注意:如果要避免创建重复的节点或关系,则两种方法都应使用MERGE而不是CREATE
。您应该仔细阅读MERGE的文档,以便了解如何正确使用它,但是上述查询非常简单,以至于用CREATE
替换MERGE
是安全的。
与其将数据预处理为密码格式,例如:
match (a1:link {description:"www.samplelink.com/example1"})
match (a2:link {description:"www.samplelink.com/example2"})
match (a3:link {description:"www.samplelink.com/example3"})
...x6,000
create (a1)-[:REF]->(a3)
create (a1)-[:REF]->(a47)
create (a5832)-[:REF]->(a9)
...x5,000
您希望将数据预处理为CSV文件,例如:
link_from,link_to
samplelink1,samplelink2
然后使用LOAD CSV
语句导入数据:
LOAD CSV WITH HEADER FROM "file:///yourfile.csv" as row
MERGE (from:link{description:row.link_from})
MERGE (to:link{description:row.link_to})
MERGE (from)-[:REF]->(to)
通过正确的索引设置,导入应该花费一秒钟的时间。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。