在big neo4j图中快速搜索未连接的节点

时间:2016-12-06 09:56:10

标签: neo4j cypher database-performance graph-databases nosql

所以,我已经从关系数据库中创建了一个Neo4j图数据库。图数据库有大约700万个节点,节点之间有大约900万个关系。

我现在想要找到所有没有连接到具有特定标签的节点的节点(让他们称之为未连接的节点)。例如,我有带标签的节点" Customer"和"订单" (让他们称他们为顶级节点)。我想找到与这些顶级节点没有关系的所有节点。这种关系不必是直接的,节点可以通过其他节点连接到顶级节点。

我有一个cypher查询可以解决这个问题:

MATCH (a) WHERE not ((a)-[*]-(:Customer)) AND not ((a)-[*]-(:Order)) RETURN a; 

可以想象,查询需要很长时间才能执行,性能很差。很可能是因为无关的关系,并且因为通过多少节点可以建立关系并不重要。但是,关系方向并不重要,我需要确保没有从任何节点到顶级节点之一的路径。

有没有办法更快地找到未连接的节点?请注意,数据库非常大,并且有超过2个标记标记顶级节点。

2 个答案:

答案 0 :(得分:0)

您可以尝试这种方法,这涉及更多操作,但可以批量运行以获得更好的性能(请参阅APOC过程库中的apoc.periodic.commit())。

我们的想法是首先将标签(例如:未连接)应用于图表中的所有节点(使用apoc.periodic.commit批量执行),然后使用该标签获取批量顶级节点,与所有节点匹配子图中的节点从它们延伸并删除该标签。

当你最终用完了顶级节点:未连接标签(意味着所有顶级节点及其子图不再具有此标签)时,图中剩余的唯一节点:未连接标签未连接到你的顶级节点。

这种操作的任何方法都可能很慢,但再次优势是你可以批量处理,如果你被打断,你可以恢复。完成查询后,所有相关的未连接节点现在都会标记为方便您进一步处理。

另外,最后一点,在Neo4j无向关系中,语法中没有箭头() - [*] - ()。

答案 1 :(得分:0)

MATCH (a) 
WHERE 
 not (a:Customer OR a:Order)
 AND shortestPath((a)-[*]-(:Customer)) IS NULL 
 AND shortestPath((a)-[*]-(:Order)) IS NULL
RETURN a;

如果你可以添加rel-types,它会更快。 进一步的优化可以是检查:客户路径的节点:订单节点,反之亦然。即

NONE(n in nodes(path) WHERE n:Order)

一般来说,这可能是一个固定的操作,即 将所有订单和客户节点并行扩展为两组 并计算两组之间的重叠。

然后从总节点数中删除重叠。

我在这里添加了一个apoc的问题,以添加这样的函数或过程

https://github.com/neo4j-contrib/neo4j-apoc-procedures/issues/223