为什么我的九步路径Cypher在一个小型数据库上的查询没有完成?

时间:2014-06-24 16:28:37

标签: neo4j cypher

我们正在为我们的应用程序评估Neo4J,针对一个总共约20K节点,150K属性和100K关系的小型测试数据库进行测试。分支因子是约100个关系/节点。服务器和版本信息低于[1]。 Cypher的查询是:

MATCH p = ()-[r1:RATES]-(m1:Movie)-[r2:RATES]-(u1:User)-[r3:RATES]-(m2:Movie)-[r4:RATES]-()
RETURN r1.id as i_id, m1.id, r2.id, u1.id, r3.id, m2.id, r4.id as t_id;

(第一个和最后一个空节点对我们来说并不重要,但我没有看到如何从关系开始。)

几个小时后我杀了它。也许我希望Neo4J避免组合爆炸,期待太多。我尝试调整一些服务器参数,但没有进一步。

我的主要问题是我正在尝试做什么(九步路径查询)对于Neo4J是否合理,或者就此而言,任何图形数据库都是合理的。我意识到九个步骤是一个非常深入的搜索,一个多次触及数据库中的每个节点,但不幸的是,这是我们的研究需要做的。

期待你的想法。

[1]系统信息:

  • Linux服务器有32个处理器和64GB内存。
  • Neo4j - 图形数据库内核(neo4j-kernel),版本:2.1.2。
  • java版“1.7.0_60”,Java(TM)SE运行时环境(版本1.7.0_60-b19),Java HotSpot(TM)64位服务器VM(版本24.60-b09,混合模式)

1 个答案:

答案 0 :(得分:3)

为了回答你的主要问题,Neo4j在进行可变长度查询时没有问题,这种查询不会导致搜索空间出现组合爆炸(由于你的分支因素,指数时间复杂度)。

然而,可以对您的Cypher查询进行优化。

MATCH ()-[r1:RATES]->(m1:Movie), 
      (m1)<-[r2:RATES]-(u1:User),
      (u1)-[r3:RATES]->(m2:Movie),
      (m2)<-[r4:RATES]-()
RETURN r1.id as i_id, m1.id, r2.id, u1.id, r3.id, m2.id, r4.id as t_id;

话虽这么说,Cypher在这些类型的查询中有一些当前的限制。我们将这些查询称为“图形全局操作”。当您运行的查询在没有特定起点的情况下全局触摸图形时,计算以及对磁盘的写入和读取都可能导致性能瓶颈。通过HTTP REST返回大型有效负载时,您将在网络中遇到数据传输限制。

要测试由于网络数据传输限制而导致的查询响应时间之间的差异,请将上一个查询与以下内容进行比较:

MATCH ()-[r1:RATES]->(m1:Movie), 
      (m1)<-[r2:RATES]-(u1:User),
      (u1)-[r3:RATES]->(m2:Movie),
      (m2)<-[r4:RATES]-()
RETURN count(*)

响应时间内查询之间的差异应该很大。

那你有什么选择?

选项1:

使用Neo4j的Java API在Java中编写一个Neo4j非托管扩展,该扩展在JVM中运行。您的Cypher查询可以强制转换为遍历内存中图形的遍历描述。看到你有64GB的内存,你的Java堆应该被配置,以便Neo4j可以访问70-85%的可用内存。

您可以在此处了解有关Neo4j Java API的更多信息:http://docs.neo4j.org/chunked/stable/server-unmanaged-extensions.html

选项2:

调整Neo4j的性能配置以在内存中运行图形并优化Cypher查询以限制通过网络传输的数据量。对于图表全局操作,性能仍然不是最佳的。