为什么allshortestpath这么慢?

时间:2019-04-03 10:59:34

标签: python neo4j cypher

我用python和neo4j库创建了一些图形数据库。图有5万个节点和10万个关系。

如何创建节点:

CREATE (user:user {task_id: %s, id: %s, root: 1, private: 0})

如何建立关系:

 MATCH (root_user), (friend_user) WHERE root_user.id = %s
                                  AND root_user.task_id = %s  
                                  AND friend_user.id = %s
                                  AND friend_user.task_id = %s
                    CREATE (root_user)-[r: FRIEND_OF]->(friend_user) RETURN root_user, friend_user 

我如何搜索节点之间的所有路径:

MATCH (start_user:user {id: %s, task_id: %s}), 
      (end_user:user {id: %s, task_id: %s}), 
      path = allShortestPaths((start_user)-[*..3]-(end_user)) RETURN path

在50k图表上缓慢滚动,大约30-60分钟。而且我不明白为什么。我尝试像这样创建索引:

CREATE INDEX ON :user(id, task_id)

但没有帮助。你能帮助我吗?谢谢。

1 个答案:

答案 0 :(得分:0)

永远不要生成包含N个基本相同的Cypher代码的细微变化的长Cypher查询。这非常慢,并且占用大量内存。

相反,您应该将parameters传递给一个更简单的Cypher查询。

例如,在创建节点时,可以将UNWIND $data AS d CREATE (user:user {task_id: d.taskId, id: d.id, root: 1, private: 0}) 参数传递给以下Cypher代码:

data

您传递的taskId参数值将是一个映射列表,每个映射将包含一个idUNWINDdata子句将d列表“展开”为单独的:user映射。这样会更快。

需要使用您的关系创建代码来完成类似的工作。

此外,为了使用任何MATCH索引,您的:user子句必须在相关节点模式中指定MATCH (root_user:user), (friend_user:user) ... 标签。否则,您将要求Cypher扫描所有节点,而不管标签如何,这种处理将无法利用索引。例如,相关查询应以以下内容开头:

Exception