Search code examples
tinkerpop3amazon-neptunetinkergraph

How can I add a new Vertex only if it is possible to add an Edge too?


I need to add a new Vertex with an Edge. My code is something like:

g.V().addV("Vertex").addE("MyEdge").to(V().has("OtherVertex", "name", "test"))

If V().has("OtherVertex", "name", "test") return a Vertex, everything works fine. My problem is if the OtherVertex doesn't exist, Gremlin add the new Vertex without edges. I would like to add the new Vertex only if I can create the Edge. I am using Gremlin-server for developing. My guess is, I could try to use Transactions, but I am not sure if AWS Neptune support it now.

Any suggestion? Thanks.


I think, avoiding transactions, I realize that I can select OtherVertex first. If it doesn't exist, the query will not create a new Vertex:

g.V().has("OtherVertex", "name", "test").as('t').addV("Vertex").as('v').addE("MyEdge").from('v').to('t')

Solution

  • As you wrote, this is the correct approach:

    g.V().has("OtherVertex", "name", "test").as('t').
      addV("Vertex").as('v').addE("MyEdge").from('v').to('t')
    

    I would just add something in relation to your initial attempt that showed:

    g.V().addV("Vertex")
    

    I think you simply meant to start with:

    g.addV("Vertex")
    

    If you go with the former you create some unintended problems:

    gremlin> g = TinkerGraph.open().traversal()
    ==>graphtraversalsource[tinkergraph[vertices:0 edges:0], standard]
    gremlin> g.V().addV('person')
    gremlin> g.V().addV('person')
    gremlin> g
    ==>graphtraversalsource[tinkergraph[vertices:0 edges:0], standard]
    

    Note that nothing gets added for an empty graph. That is because V() returns no vertices and therefore there is nothing in the pipeline to trigger addV() with. Let's assume you have some data though:

    gremlin> g = TinkerFactory.createModern().traversal()
    ==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
    gremlin> g.V().addV('person')
    ==>v[13]
    ==>v[14]
    ==>v[15]
    ==>v[16]
    ==>v[17]
    ==>v[18]
    gremlin> g.V().addV('person')
    ==>v[19]
    ==>v[20]
    ==>v[21]
    ==>v[22]
    ==>v[23]
    ==>v[24]
    ==>v[25]
    ==>v[26]
    ==>v[27]
    ==>v[28]
    ==>v[29]
    ==>v[30]
    

    Now, there's an even worse problem in that we're adding one vertex for every existing vertex as V() now returns all the vertices in the graph on each execution.

    As a final note, please see this Gremlin Recipe for ways to do get-or-create type operations as it's related to this conditional sort of mutation that you're doing now.