Neo4j扩展查询非常慢

时间:2017-12-30 08:49:07

标签: neo4j

我正在使用neo4j-community-3.3.0,会有:

  • 节点:20000,
  • 关系:72000,
  • 属性per_node:1,
  • 属性per_relationship:1

我的机器有:

  • RAM:16G,
  • dbms.memory.pagecache.size:6G,
  • dbms.memory.heap.max_size:8G

我希望将所有节点连接到节点,并将与这些节点相关的总和关系属性发送到csv文件。我想对数据库中的所有节点执行此操作。

我有关系属性的索引 -

INDEX ON :Amount(AMNT), and a Constraints on node property-CONSTRAINT ON (customer:Customet) ASSERT customer.ACCT IS UNIQUE

我的查询是:

 CALL apoc.export.csv.query("MATCH (x:Customer) with x CALL
 apoc.cypher.run(\"CALL apoc.path.expandConfig(x,
 {relationshipFilter:'Amount>', labelFilter:'+Customer', uniqueness:
 'NODE_PATH' } ) YIELD path return path as path\", {x:x}) YIELD value
 unwind nodes(value.path) as nodes unwind relationships(value.path) as
 rels  with collect(distinct nodes) as nodelist, collect(distinct rels)
 as rellist,x.ACCT as CustNumber with size(nodelist) as numOfMember,
 reduce(s = 0, r IN rellist | s + TOINT(r.AMNT)) AS totalAMNT
 ,CustNumber where (numOfMember > 100) and  ( totalAMNT > 100000) return
 CustNumber,numOfMember,totalAMNT ","results.csv",{});

但查询运行速度非常慢,很长一段时间后我收到此错误:

  

错误取消发送返回标头;嵌套异常   是:java.net.SocketException:软件导致连接中止:recv   失败

请帮帮我。

1 个答案:

答案 0 :(得分:1)

我感觉你的两个背靠背的UNWINDS正在创建大量的结果记录(路径中每个节点的交叉产品与路径中的每个关系,以及来自所有扩展的每条可能路径:Customer节点)。不要这样做,你可能会砸到你的堆。

另外,我强烈建议您在一个单一的客户节点上查询内部查询,看看发生了什么,特别是查询中行的增加情况。

我在摸不着为什么你在这里使用apoc.cypher.run()来打电话给apoc.path.expandConfig()。除非有充分的理由,否则我建议完全删除apoc.cypher.run()的使用。

我们还可以使用UNWINDing的一些替代方法,使用一些APOC过程来展平和获取集合中的不同值,并提前过滤一些结果以避免处理仅在以后过滤掉的记录。

也许尝试这样的事情:

CALL apoc.export.csv.query("
MATCH (x:Customer) 
CALL apoc.path.expandConfig(x, {relationshipFilter:'Amount>', labelFilter:'+Customer', uniqueness: 'NODE_PATH' } ) YIELD path
WITH x, collect(nodes(path)) as allPathNodes, collect(relationships(path)) as allPathRels
WITH x, size(apoc.coll.toSet(apoc.coll.flatten(allPathNodes))) as numOfMember, allPathRels
WHERE numOfMember > 100
WITH x, numOfMember, apoc.coll.toSet(apoc.coll.flatten(allPathRels)) as rellist
WITH x, numOfMember, apoc.coll.sum([r in rellist | TOINT(r.AMNT)]) as totalAMNT
WHERE totalAMNT > 100000
RETURN x.ACCT as CustNumber, numOfMember, totalAMNT ","results.csv",{});

根据您的图表,expandConfig()调用可能很昂贵。您可能想看看是否可以完成此调用并在合理的时间内获得预期的路径数。试试这个:

MATCH (x:Customer) 
CALL apoc.path.expandConfig(x, {relationshipFilter:'Amount>', labelFilter:'+Customer', uniqueness: 'NODE_PATH' } ) YIELD path
RETURN count(path) as paths

如果您只想要到每个节点的单个路径而不是每个节点的所有路径,那么您可以使用apoc.path.spanningTree()(或使用NODE_GLOBAL唯一性,这将是等效的)来获得更有效的查询。

相关问题