Neo4j 无限运行空间查询

问题描述 投票:0回答:1

我有一个 Neo4j 数据库,它有两种不同的节点类型,一种用于爆破孔数据,一种用于地质块模型。我花了很大的努力来导入这些节点的数据以从 csv 填充,但我能够通过 CALL 方法实现这一点。块模型有大约 300 万个节点,可能有 12 个属性,爆破孔样本节点有大约 30k。我正在努力想出一个有效的查询来创建存储计算距离的空间关系。

我能够运行以下查询。

CALL apoc.periodic.iterate(
  "MATCH (b:BlastholeSamples) RETURN b" LIMIT 100,
  "WITH b
   MATCH (g:GeologicalBlock)
   WHERE g.location.x >= b.location.x - 100 AND g.location.x <= b.location.x + 100
   AND g.location.y >= b.location.y - 100 AND g.location.y <= b.location.y + 100
   AND point.distance(b.location, g.location) <= 100  
   AND abs(b.midZ_D - g.ELEV) < 0.5  
   WITH b, g, point.distance(b.location, g.location) AS distance  
   CREATE (b)-[r:LOCATED_IN {distance: distance}]->(g)", 
  {batchSize: 50, iterateList: true}
);

目的是在炮孔样本周围创建一个边界框以进行关系评估。如果地质块点在框中,则创建关系并存储距离。

在此查询之前,我确实根据 x、y、z 值创建了索引,并为笛卡尔创建了位置属性。

该查询不可能是最佳的,因为在我终止它之前它运行了超过 18 小时。这似乎太长了。

它似乎确实有效,并为某些节点生成了结果,这非常棒。
绽放图像

请帮助优化或提供一些我可能错过的提示?我是 neo4j 和 cypher 的超级新手。

neo4j cypher spatial
1个回答
0
投票

我假设您为 GeologicalBlock.location 创建了一个

POINT 索引
。 POINT 索引仅由某些空间函数使用(请参阅链接中的
Supported predicates
表)。因此,您应该:(1) 存储 3D 点(如果您尚未这样做),并且 (2) 使用
point.withinBBox()
预过滤点。

例如,假设

BlastholeSamples.location
GeologicalBlock.location
存储为“笛卡尔 3D”点,这样的方法可能适合您:

CALL apoc.periodic.iterate(
  "MATCH (b:BlastholeSamples) RETURN b.location AS loc LIMIT 100",
  "MATCH (g:GeologicalBlock)
   WHERE point.withinBBox(g.location,
     point({x: loc.x-100, y: loc.y-100, z: loc.z-100}),
     point({x: loc.x+100, y: loc.y+100, z: loc.z+100}))
   AND point.distance(loc, g.location) <= 100
   CREATE (b)-[r:LOCATED_IN {distance: point.distance(loc, g.location)}]->(g)", 
  {batchSize: 50, iterateList: true}
);
© www.soinside.com 2019 - 2024. All rights reserved.