0

我有一个使用 Neo4J Spatial 插件运行的 Neo4J 实例。在其中,我有一个大约 3.5 k 节点的图,每个节点都有相同的标签,我们称之为 Basket。每个篮子都与同一城市的一个物理位置相关,这些篮子的密度变化很大。我计算了每个篮子与其 600m 内所有邻居之间的步行时间,并将这些存储为节点之间的非空间(有向)关系。因此,一些篮子似乎作为一个大集群的一部分存在,而其他篮子几乎独立存在,与其他篮子只有一种关系或几乎没有关系。

我的用户有一个问题:他们希望从一个地方开始,在另一个地方结束,一路访问任意数量的用户定义的篮子。我的程序旨在为用户提供一些路线选项(作为节点序列 - 我将在后面对实际的如何步行部分进行排序),计算第 n 个最短路径。

我已经编写了一个密码查询来执行此操作,如下所示。

start a = node(5955), b=node(6497) 
WITH a,b 
    MATCH p=((a)-[r:IS_WALKABLE_TO*4..5]->(b)) 
RETURN p

NB - 节点59556497是我选择的两个节点,相距约 2 英里,在这种情况下,我决定沿途选择 4 到 5 个篮子。

但是,我一直遇到内存不足的异常,因此希望得到有关如何减少此问题的内存需求以使其在可接受的 1 到 6 秒的时间内在负担得起的服务器上执行的建议。

我的理解是 Neo4j 不会执行笛卡尔积来找到解决方案,而是“挑选每个节点并从每个节点中嗅探,直到找到合适大小的连接”(请原谅我的措辞!),所以我我对堆内存错误感到困惑。

我改进程序的想法是:

  1. 不知何故,将查询的路径查找部分限制在边界框内的节点上,由开始和结束节点的位置确定(即,在每个方向上增加 500 m,然后将查询限制在这些节点上)。但是,我找不到任何有关如何执行此操作的文档 - 是否可以不必为每个查询创建另一个空间层?

  2. 以不会产生内存错误的方式重新编写查询 - 这很容易吗?

  3. 完全停止使用 Neo4J 并编写一个算法以使用替代语言手动完成。如果是这样,你会推荐什么语言?C?C++/C#?或者我可以坚持使用 Python / Ruby / Java / Go 吗?(或者,我什至认为我可以在 PHP 中非常有效地做到这一点,但我不确定那是否是一个疯狂的时刻)。

任何关于如何解决这个问题的帮助和建议都非常感谢!

4

2 回答 2

1

我认为由于图形的密集连接形状,由于重复的中间节点,您很容易最终得到数亿条可能的路径。

您应该在查询中添加一个LIMIT 100,然后它会停止搜索路径。

a另一个想法是重写您的查询以首先找到周围(并且可能b)的不同起点。

start a = node(5955), b=node(6497) 
MATCH (a)-[:IS_WALKABLE_TO]->(a1)-[:IS_WALKABLE_TO]->(a2)
WITH a, b, a2, collect(a1) as first
MATCH p = shortestPath((a2)-[:IS_WALKABLE_TO*..2]->(b)) 
RETURN count(*)

// or
UNWIND first as a1
RETURN [a,a1] + nodes(p) as path
于 2015-12-27T15:16:50.537 回答
1

您最好将此 Cypher 查询重构为 Java 代码,使其成为非托管扩展。然后,您的 java 代码可能会使用 Traversal API 或GraphAlgoFactory.pathsWithLength()

于 2015-12-27T09:56:52.243 回答