如何在一个非常大的图中添加边缘(关系)Neo4j

时间:2015-11-02 09:32:28

标签: database graph neo4j cypher neo4jclient

我有一个简单的图形模型。在此图表中,每个节点都有一个属性 {NodeId} 。每个Edge将链接两个节点而没有其他属性。它是一个有向图,有大约10 ^ 6个节点。

这是我的情况: 我首先在属性 {NodeId} 上创建了索引。然后我创建了10 ^ 6个节点。在这个时候,我有一个10 ^ 6节点,没有边缘的图形。 当我想随机添加边缘时,我发现速度非常慢。我每秒只能添加大约40条边。

我错过了任何配置吗?我不认为这是一个合理的速度。

添加边的代码:

public static void addAnEdge(GraphClient client, Node a, Node b)
    {
        client.Cypher
        .Match("(node1:Node)", "(node2:Node)")
        .Where((Node node1) => node1.Id == a.Id)
        .AndWhere((Node node2) => node2.Id == b.Id)
        .Create("node1-[:Edge]->node2")
        .ExecuteWithoutResults();
    }

我应该在边缘添加索引吗?如果是这样,如何在neo4jClient中做到这一点? 谢谢你的帮助。

将我的所有查询批处理到一个事务中是一个很好的信号。我在浏览器中执行以下语句(http://localhost:7474):

MATCH (user1:Node), (user2:Node)
WHERE user1.Id >= 5000000 and user1.Id <= 5000100 and user2.Id >= 5000000 and user2.Id <= 5000100
CREATE user1-[:Edge]->user2

在此语句中,我在一个事务中创建了10000个边。所以我认为http开销现在并不那么严重。结果是:

Created 10201 relationships, statement executed in 322969 ms.

这意味着我每秒增加30条边。

2 个答案:

答案 0 :(得分:3)

理想的解决方案是在一个参数映射中传递要关联的节点对,然后使用UNWIND,您可以迭代这些对并创建关系,只要您在{{1}上有索引,这就非常有效。 Id节点的属性。

我不知道你怎么能用Neo4jClient做到这一点,但这里是Cypher声明:

Node

要与查询一起发送的参数应具有以下形式:

UNWIND {pairs} as pair
MATCH (a:Node), (b:Node)
WHERE a.Id = pair.start AND b.Id = pair.end
CREATE (a)-[:EDGE]->(b)

<强>更新

Neo4jClient作者在Neo4jClient中给了我相同的代码:

{
  "parameters": {
    "pairs": [
      {
        "start": "1",
        "end": "2"
      },
      {
        "start": "3",
        "end": "4"
      }
    ]
  }
}

答案 1 :(得分:0)

在您更新的Cypher查询中,您MATCH所有节点的笛卡尔积。那很慢。看看the EXPLAIN of your query

请参阅此问题,了解如何处理笛卡儿产品:Why does neo4j warn: "This query builds a cartesian product between disconnected patterns"?

你有Id财产的索引吗?理想情况下,您应该use a uniqueness constraint。这会自动添加一个非常快的索引。

在您的查询中,首先尝试MATCH第一个节点,使用WITH在列表中收集它们,然后MATCH第二批节点:

MATCH (user1:Node)
WHERE user1.id >= 50000 and user1.id <= 50100
WITH collect(user1) as list1
MATCH (user2:Node)
WHERE user2.id >= 50000 and user2.id <= 50100
UNWIND list1 as user1
CREATE (user1)-[:EDGE]->(user2)