好的,首先,我使用Neo4jClient来实现这一点,我添加了一个
INDEX
数据库使用:
CREATE INDEX ON :MyClass(Id)
这对于这种工作方式很重要,因为这样可以更快地插入数据。
public class MyClass
{
public int Id {get;set;}
public string AValue {get;set;}
public ICollection<int> LinkToIds {get;set;} = new List<int>();
}
它有一个
Id
我会把它关掉,然后
string
LinkToIds
属性是此实例链接到的ID的集合。
生成我的
MyClass
我使用此方法随机生成的实例:
private static ICollection<MyClass> GenerateMyClass(int number = 50000){
var output = new List<MyClass>();
Random r = new Random((int) DateTime.Now.Ticks);
for (int i = 0; i < number; i++)
{
var mc = new MyClass { Id = i, AValue = $"Value_{i}" };
var numberOfLinks = r.Next(1, 10);
for(int j = 0; j < numberOfLinks; j++){
var link = r.Next(0, number-1);
if(!mc.LinkToIds.Contains(link) && link != mc.Id)
mc.LinkToIds.Add(link);
}
output.Add(mc);
}
return output;
}
然后我用另一种方法把它分成更小的“批”:
private static ICollection<ICollection<MyClass>> GetBatches(ICollection<MyClass> toBatch, int sizeOfBatch)
{
var output = new List<ICollection<MyClass>>();
if(sizeOfBatch > toBatch.Count) sizeOfBatch = toBatch.Count;
var numBatches = toBatch.Count / sizeOfBatch;
for(int i = 0; i < numBatches; i++){
output.Add(toBatch.Skip(i * sizeOfBatch).Take(sizeOfBatch).ToList());
}
return output;
}
然后要实际添加到数据库中:
void Main()
{
var gc = new GraphClient(new Uri("http://localhost:7474/db/data"), "neo4j", "neo");
gc.Connect();
var batches = GetBatches(GenerateMyClass(), 5000);
var now = DateTime.Now;
foreach (var batch in batches)
{
DateTime bstart = DateTime.Now;
var query = gc.Cypher
.Unwind(batch, "node")
.Merge($"(n:{nameof(MyClass)} {{Id: node.Id}})")
.Set("n = node")
.With("n, node")
.Unwind("node.LinkToIds", "linkTo")
.Merge($"(n1:{nameof(MyClass)} {{Id: linkTo}})")
.With("n, n1")
.Merge("(n)-[:LINKED_TO]->(n1)");
query.ExecuteWithoutResults();
Console.WriteLine($"Batch took: {(DateTime.Now - bstart).TotalMilliseconds} ms");
}
Console.WriteLine($"Total took: {(DateTime.Now - now).TotalMilliseconds} ms");
}
在我老化的机器上(现在已经5-6岁了),大约需要20秒才能放入50000个节点,大约需要500000个关系。
UNWIND
-在这里我
展开
node
. 然后我可以访问属性(
node.Id
MERGE
一个节点。在第一次放松的时候-我总是
SET
新创建的节点(
n
节点
AValue
)准备好了。
所以直到第一次
With
我们创建了一个新节点
标签,以及它的所有属性集。现在。这包括
如果你是一个整洁的人-你可能想删除。我把那留给你自己。
在第二个
展开
我们利用这个事实
属性是一个数组,并使用它创建一个稍后将填充的“占位符”节点,然后在
n个
以及
n1
n1型
我们将使用该节点,当我们在第一个
展开
我们将设置占位符的所有属性。
合并
和
在Neo4j文档中。