Neo4J - 嵌套节点导致JVM上的java.lang.OutOfMemoryError

时间:2017-03-21 16:57:19

标签: database neo4j cypher data-modeling

我刚刚开始练习Neo4J,在阅读了一些文档和教程后,我创建了我的数据模型,在处理嵌套节点时遇到了一个问题,这个节点与另一个具有相同标签的节点相关所以(关系中有多少级别没有最大值)

Here is a quick overview of my graph model

所以基本上一个类型属于一个Person,然后每个类型都可以是另一个类型的子类。我正在尝试的是读取与人相关的所有类型(以及与最高类型节点相关的子类型节点)。每人有2000-3000种类型,嵌套类型节点可以多达10级。

以下是我正在尝试的内容:

MATCH (p:Person{name: 'Bill'})-[*0..]-(t:Type) RETURN p, t

这使得JVM内存不足,数据库暂时托管在一个2GB内存的盒子上,但稍后会升级,但我还是觉得我错过了什么,这样的查询怎么会需要这么多的内存?

如果我使用深度限制运行相同的查询,则查询可以在5深度运行,所以

MATCH (p:Person{name: 'Bill'})-[*0..4]-(t:Type) RETURN p, t

这个查询工作正常,给了我一个人约2308个节点和2307个关系。

解决方案只是将数据库托管在具有更多内存的盒子上,但即便如此,当数据库同时收到多个请求时会发生什么?

我觉得我错过了什么。

2 个答案:

答案 0 :(得分:2)

无限长的可变长度路径是众所周知的内存和时间密集型,因为搜索树的大小随着搜索的深度呈指数级增长。

除此之外,我认为您的查询花了这么长时间还有另一个原因。您查询的关系模式(-[*0..]-)是无方向性的。因此,变长搜索不仅会从子类型转到其父类型,还会从父类型返回到其所有子类型。这会导致搜索您不感兴趣的许多类型(可能是所有类型),并且结果将无效。

由于您的数据模型的关系都指向Person的方向,这可能对您更有效(也就是说,您可能能够使用更高的上限而不是4 ;在这个例子中,我使用了10):

MATCH (p:Person {name: 'Bill'})<-[*..10]-(t:Type)
RETURN p, t

此查询使用方向关系模式。它还允许较低的可变长度绑定默认为1(因为大概没有Person节点也是Type节点,无论如何),这将消除相同的浪费处理时间。

顺便说一下,如果你还没有Person(name)上的索引,你应该考虑添加一个来加速查找Person节点(尽管这不是你的原因)内存不足了。)

答案 1 :(得分:0)

您可能希望在此处使用APOC程序。你似乎对路径本身,只是节点感兴趣,所以程序apoc.path.subgraphNodes()可以解决问题(确保你正在使用正确的方向:CHILD_OF关系遵循):< / p>

MATCH (p:Person{name: 'Bill'})<-[:BELONGS_TO]-(t:Type)
CALL apoc.path.subgraphNodes(t, {relationshipFilter:'CHILD_OF>'}) YIELD node
RETURN p, node