gremlintinkerpop3amazon-neptune

Gremlin Coalesce To Add Multiple Vertices and Edges


Right now I am able to generate a query to create as many vertices and edges as I want.

e.g.

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

^^^^^^^^^^^^^ This works. Easy enough right? Now lets create a gremlin query that only creates these vertices if their label is unique. Then create an edge between the two.

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')

^^^^^^^^^^^^^This does not work

hopefully you can understand what I am trying to do though. Can anyone help me?

Thanks


Solution

  • You have a fold() which is a ReducingBarrierStep that follows after your step label at as('a') and the path history to "a" is lost after that step. You can read more about this aspect of Gremlin here.

    You just need to re-write your query to account for that - one way might be to just aggregate() the value of "a" rather than simply naming the step "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]
    

    If you need to return all the elements, just project() the returned edge and transform the results as necessary:

    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]]
    

    Of course, using a select() at the end might not be so bad either:

    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]]