基于现有的关系表,我想创建一个图表。该表具有以下两列ItemId和ParentItemId。 ParentItemId可以为null。该图表将包含父项和子项之间的项目和“子”关系。为此,我使用了以下代码:
public class ItemRecord
{
public int ItemId;
public int? ParentItemId;
}
public class ItemNode
{
public int ItemId;
}
public void BuildGraph(IEnumerable<ItemRecord> data)
{
var graphClient = new GraphClient(new Uri("http://localhost:7474/db/data"), "user", "pass");
graphClient.Connect();
var tran = graphClient.BeginTransaction();
var nodes = data.Select(item => new ItemNode {ItemId = item.ItemId});
try
{
//creates the nodes in a single operation
graphClient.Cypher
.Create("(n:Item {nodes})")
.WithParam("nodes", nodes)
.ExecuteWithoutResults();
///creates the relations
foreach (var nodeItem in data)
{
if (!nodeItem.ParentItemId.HasValue)
{
continue;
}
graphClient.Cypher
.Match("(source:Item)", "(destination:Item)")
.Where((ItemNode source) => source.ItemId == nodeItem.ParentItemId.Value)
.AndWhere((ItemNode destination) => destination.ItemId == nodeItem.ItemId)
.Create("source-[:Parent]->destination")
.ExecuteWithoutResults();
}
tran.Commit();
}
catch (Exception)
{
tran.Rollback();
}
}
首先,我创建节点,然后创建它们之间的关系。这种方法很慢。对于1000件物品大约需要。 10秒问题是我为每个关系调用neo4j服务器。有没有办法在单个语句中创建图形?我怎样才能提高性能?
答案 0 :(得分:2)
TL; DR; - import tool example
您可以使用Neo4j服务器提供的import tool。它能够非常快速地导入大量数据。
工具接受输入的CSV文件。所以,你应该做的是:
1)编写将所有数据处理成CSV文件并将其保存到磁盘上的脚本(或类似内容) 2)使用导入工具并将准备好的CSV文件导入数据库。
注意:在此过程中不会创建索引。稍后应使用标准的Neo4j功能添加它们。
示例:
<强> nodes.csv 强>
ItemId:ID,:LABEL,value
item1,Item,"some"
item2,Item,"other"
item3,Item,"another"
<强> relationships.csv 强>
:START_ID,:END_ID,:TYPE
item1,item2,Parent
item1,item3,Parent
并命令:
neo4j-import --into path_to_target_directory --nodes nodes.csv --relationships relationships.csv
答案 1 :(得分:0)
您是否尝试过使用UNWIND
?
我有以下内容,它在大约4秒钟内创建100,000个节点(或者在300毫秒内创建1,000个节点)。显然我不得不假装&#39;一些ItemRecord
个实例,因此它可能不完全相同 - 并且需要在您的ItemId
属性上设置索引。
以下代码应该只是当前方法中的复制/替换:
public void BuildGraph(IEnumerable<ItemRecord> data)
{
var graphClient = new GraphClient(new Uri("http://localhost:7474/db/data"), "user", "pass");
graphClient.Connect();
//Create the Index.
graphClient.Create("INDEX ON :Item(ItemId)").ExecuteWithoutResults();
var tran = graphClient.BeginTransaction();
var nodes = data.Select(item => new ItemNode {ItemId = item.ItemId});
try
{
//creates the nodes in a single operation
graphClient.Cypher
.Create("(n:Item {nodes})")
.WithParam("nodes", nodes)
.ExecuteWithoutResults();
var nodesWithParents = data.Where(n => n.ParentItemId.HasValue);
//creates the relations
graphClient.Cypher
.Unwind(nodesWithParents, "node")
.Match("(source:Item {ItemId: node.ItemId}),(destination:Item {ItemId : node.ParentItemId})")
.Create("source-[:Parent]->destination")
.ExecuteWithoutResults();
tran.Commit();
}
catch (Exception)
{
tran.Rollback();
}
}