Graph 如何在Gremlin中进行有效的批量升级(插入新顶点或更新属性)?

Graph 如何在Gremlin中进行有效的批量升级(插入新顶点或更新属性)?,graph,gremlin,tinkerpop,tinkerpop3,amazon-neptune,Graph,Gremlin,Tinkerpop,Tinkerpop3,Amazon Neptune,上下文: 我有一个大约有2000个顶点和6000条边的图,随着时间的推移,这可能会增长到10000个顶点和100000条边。目前,我正在使用以下遍历查询升级新顶点: 向上插入顶点和边 此处的目的是查找名为foo的顶点,如果找到,则更新其模型属性,否则创建一个新顶点并设置模型属性。发出两次:一次用于源顶点,然后用于目标顶点。 创建两个相关顶点后,将发出另一个查询以创建它们之间的边: queryEdge = "g.V('id_of_source_vertex').coalesce(

上下文

我有一个大约有2000个顶点和6000条边的图,随着时间的推移,这可能会增长到10000个顶点和100000条边。目前,我正在使用以下遍历查询升级新顶点:

向上插入顶点和边

此处的目的是查找名为foo的顶点,如果找到,则更新其
模型
属性,否则创建一个新顶点并设置
模型
属性。发出两次:一次用于源顶点,然后用于目标顶点。
创建两个相关顶点后,将发出另一个查询以创建它们之间的边:

queryEdge = "g.V('id_of_source_vertex').coalesce(
             outE(edge_label).filter(inV().hasId('id_of_target_vertex')), 
             addE(edge_label).to(V('id_of_target_vertex'))
             ).property(model, 2)"
在这里,如果两个顶点之间存在边,则会更新边上的
model
属性,否则会在它们之间创建边

实现这一点的伪代码如下:

for each edge in the list of new edges:
   //upsert source and target vertices:  
   execute queryVertex for edge.source
   execute queryVertex for edge.target
   // upsert edge: 
   execute queryEdge
这是可行的,但效率很低;例如,对于所提到的图表大小,需要几分钟才能完成,并且由于应用程序内的一些并发性,它只减少了几分钟的时间。当然,对于如此小的图形大小,必须有一种更有效的方法来实现这一点

问题

*我怎样才能使这些上升更快

批量加载通常应该被归入特定于提供商的工具,这些工具经过优化以处理此类任务。Gremlin并没有提供抽象来涵盖为实现TinkerPop的各种图形数据库系统提供的各种批量加载工具组。对海王星来说,这就是你如何标记你的问题,这意味着使用

特别针对您的问题,尽管您可能会看到对您所描述的方法进行了一些优化。从Gremlin的角度来看,我想通过组合现有的遍历,每个边提交一个Gremlin请求,您可以在这里看到一些节省:

g.V().has(label, name, foo).fold().
  coalesce(unfold(), 
           addV(label).property(name, foo)).
  property(model, 2).as('source').
  V().has(label, name, bar).fold().
  coalesce(unfold(), 
           addV(label).property(name, bar)).
  property(model, 2).as('target').
  coalesce(inE(edge_label).where(outV().as('source')), 
           addE(edge_label).from('source').to('target')).
  property(model, 2)

我想我没有经过测试,但希望你能理解我的想法。基本上,我们只是通过步骤标签引用内存中已经存在的顶点,这样就不需要重新查询它们。如果您继续使用Gremlin风格的批量加载,例如对边进行排序,这样您就可以批量加载更多的边,以减少顶点查找量,并以更动态的方式提交顶点/边数据,那么您也可以尝试其他策略。

我有一个类似的用例。我想插入大量顶点。我还考虑了您描述的方式,但最终得到了3次遍历:1。根据(可能是新的)ID查找所有顶点。2.为未找到的所有ID创建顶点。3.更新所有旧顶点。这要快得多。我使用的是JanusGraph tho,而不是neptune。我倾向于以一种直接回答原始帖子的方式回答小精灵问题,同时提供警告和最佳实践。您很可能会找到更好的方法来为特定的图形数据库提供程序提供套件。我想,在JanusGraph中,您甚至可以根据自己的需求找到更快的Spark批量加载方法。
g.V().has(label, name, foo).fold().
  coalesce(unfold(), 
           addV(label).property(name, foo)).
  property(model, 2).as('source').
  V().has(label, name, bar).fold().
  coalesce(unfold(), 
           addV(label).property(name, bar)).
  property(model, 2).as('target').
  coalesce(inE(edge_label).where(outV().as('source')), 
           addE(edge_label).from('source').to('target')).
  property(model, 2)