如何在非常大的图中添加边(关系)Neo4j
How to add edges(relationship) Neo4j in a very big graph
我有一个简单的图形模型。在此图中,每个节点都有一个属性 {NodeId}。每个 Edge 将 link 两个没有其他属性的节点。它是一个有向图,大约有 10^6 个节点。
这是我的情况:
我在属性 {NodeId} 上创建了索引 first.Then 我创建了 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 个边。
在您更新的 Cypher 查询中,您 MATCH
所有 个节点的笛卡尔积。那很慢。看看 the EXPLAIN
of your query.
并查看此问题以了解如何处理笛卡尔积:
你有 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)
理想的解决方案是在一个参数映射中传递要关联的节点对,然后使用 UNWIND 您可以迭代这些对并创建关系,只要您在 [= Node
个节点的 13=] 属性。
我不知道你如何使用 Neo4jClient 做到这一点,但这是 Cypher 声明:
UNWIND {pairs} as pair
MATCH (a:Node), (b:Node)
WHERE a.Id = pair.start AND b.Id = pair.end
CREATE (a)-[:EDGE]->(b)
与查询一起发送的参数应采用以下形式:
{
"parameters": {
"pairs": [
{
"start": "1",
"end": "2"
},
{
"start": "3",
"end": "4"
}
]
}
}
更新
Neo4jClient 作者好心地给了我 Neo4jClient 中的等效代码:
var parameters = new [] {
new {start = 1, end = 2},
new {start = 3, end = 4}
};
client.Cypher
.Unwind(parameters, "pair")
.Match("(a:Node),(b:Node)")
.Where("a.Id = pair.start AND b.Id = pair.end")
.Create("(a)-[:EDGE]->(b)")
.ExecuteWithoutResults();
我有一个简单的图形模型。在此图中,每个节点都有一个属性 {NodeId}。每个 Edge 将 link 两个没有其他属性的节点。它是一个有向图,大约有 10^6 个节点。
这是我的情况: 我在属性 {NodeId} 上创建了索引 first.Then 我创建了 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 个边。
在您更新的 Cypher 查询中,您 MATCH
所有 个节点的笛卡尔积。那很慢。看看 the EXPLAIN
of your query.
并查看此问题以了解如何处理笛卡尔积:
你有 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)
理想的解决方案是在一个参数映射中传递要关联的节点对,然后使用 UNWIND 您可以迭代这些对并创建关系,只要您在 [= Node
个节点的 13=] 属性。
我不知道你如何使用 Neo4jClient 做到这一点,但这是 Cypher 声明:
UNWIND {pairs} as pair
MATCH (a:Node), (b:Node)
WHERE a.Id = pair.start AND b.Id = pair.end
CREATE (a)-[:EDGE]->(b)
与查询一起发送的参数应采用以下形式:
{
"parameters": {
"pairs": [
{
"start": "1",
"end": "2"
},
{
"start": "3",
"end": "4"
}
]
}
}
更新
Neo4jClient 作者好心地给了我 Neo4jClient 中的等效代码:
var parameters = new [] {
new {start = 1, end = 2},
new {start = 3, end = 4}
};
client.Cypher
.Unwind(parameters, "pair")
.Match("(a:Node),(b:Node)")
.Where("a.Id = pair.start AND b.Id = pair.end")
.Create("(a)-[:EDGE]->(b)")
.ExecuteWithoutResults();