格雷姆林合并以添加多个顶点和边



现在,我可以生成一个查询来创建任意数量的顶点和边。

例如

g.V().
addV('vert1').as('a').
addV('vert2').as('b').
addE('has').from('a').to('b')

^^^^^^^^^^^^^ 这行得通。够容易吧?现在,让我们创建一个 gremlin 查询,该查询仅在这些顶点的标签唯一时才创建这些顶点。然后在两者之间创建一条边。

g.V().has(label,'vert1').fold().
    coalesce(
        unfold(),
        addV('vert1')
    ).as('a').
    V().has(label,'vert2').fold().
    coalesce(
        unfold(),
        addV('vert2')
    ).as('b').
    addE('has').from('a').to('b')

^^^^^^^^^^^^^这不起作用

希望你能理解我想做什么。谁能帮我?

谢谢

您有一个fold(),它是在步骤标签之后as('a')ReducingBarrierStep,并且在该步骤之后,"a"的路径历史记录将丢失。你可以在这里阅读更多关于格里姆林这方面的信息。

您只需要重写查询来说明这一点 - 一种方法可能是只aggregate()"a"的值,而不是简单地命名步骤"a":

gremlin> g = TinkerGraph.open().traversal()
==>graphtraversalsource[tinkergraph[vertices:0 edges:0], standard]
gremlin> g.V().
......1>   has(label,'vert1').fold().
......2>   coalesce(unfold(),
......3>            addV('vert1')).aggregate('a').
......4>   V().has(label,'vert2').fold().
......5>   coalesce(unfold(),
......6>            addV('vert2')).as('b').
......7>   select('a').unfold().
......8>   addE('has').to('b')
==>e[2][0-has->1]

如果需要返回所有元素,只需project()返回的边缘并根据需要转换结果:

gremlin> g.V().
......1>   has(label,'vert1').fold().
......2>   coalesce(unfold(),
......3>            addV('vert1')).aggregate('a').
......4>   V().has(label,'vert2').fold().
......5>   coalesce(unfold(),
......6>            addV('vert2')).as('b').
......7>   select('a').unfold().
......8>   addE('has').to('b').
......9>   project('e','in','out').
.....10>     by().
.....11>     by(inV()).
.....12>     by(outV())
==>[e:e[2][0-has->1],in:v[1],out:v[0]]

当然,在最后使用select()可能也不是那么糟糕:

gremlin> g = TinkerGraph.open().traversal()
==>graphtraversalsource[tinkergraph[vertices:0 edges:0], standard]
gremlin> g.V().
......1>   has(label,'vert1').fold().
......2>   coalesce(unfold(),
......3>            addV('vert1')).aggregate('a').
......4>   V().has(label,'vert2').fold().
......5>   coalesce(unfold(),
......6>            addV('vert2')).as('b').
......7>   select('a').unfold().
......8>   addE('has').to('b').as('x').
......9>   select('a','b','x')
==>[a:[v[0]],b:v[1],x:e[2][0-has->1]]

我也在寻找一种幂等方法,在单个命令中创建多个顶点并返回结果。 (我使用Cosmos DB的Gremlin API,以及使用fold的典型解决方案...合并。。。展开在链接在一起时不起作用。

通过一些实验,我想出了这个替代方案,随着您添加更多顶点,其复杂性是线性的。 我正在使用inject()人为地为第一次调用coalesce()创建一个"源"。

g.inject("0")
  .coalesce(__.V(['pk1','00']), addV('MyV')
    .property('id','00')
    .property('partitionKey','pk1')).as('x')
  .coalesce(__.V(['pk1','01']), addV('MyV')
    .property('id','01')
    .property('partitionKey','pk1'))
    .as('x')
  .coalesce(__.V(['pk1','02']), addV('MyV')
    .property('id','02')
    .property('partitionKey','pk1'))
    .as('x')
.select('x')

对于那些不关心分区键的人来说,它看起来像这样:

g.inject("0")
  .coalesce(__.V('00'), addV('MyV').property('id','00')).as('x')
  .coalesce(__.V('01'), addV('MyV').property('id','01')).as('x')
  .coalesce(__.V('02'), addV('MyV').property('id','02')).as('x')
.select('x')

此外,我们可以通过提供唯一的标签(带as()(同时在新顶点之间创建任意数量的边。

g.inject("0")
  .coalesce(__.V(['pk2','05']), addV('MyV').property('id','05')
    .property('partitionKey','pk2')
    .property('ABC','123467890'))
    .as('x').as('a')
  .coalesce(__.V(['pk2','06']), addV('MyV').property('id','06')
    .property('partitionKey','pk2')
    .property('ABC','123467890'))
    .as('x')
  .coalesce(g.E(['pk2','07']), addE('MyE').property('id','07').from('a'))
    .as('x')
.select('x')