Search code examples
graphgremlintinkerpopamazon-neptunegremlinpython

Graph/Gremlinpython: Upsert 2 vertices and an edge from one to the other


I try to add (if they do not exist) 2 vertices and add an edge from the first to the other in a single query. It would look like:

g.V().has("label1", "property1", "value1").fold().coalesce(
        __.unfold(),
        g.addV("label1").property("property1", "value1")
    ).as_("a").V().has("label2", "property2", "value2").fold().coalesce(
        __.unfold(),
        g.addV("label2").property("property2", value2)
    ).coalesce(
        __.inE("link").where(__.outV().as_("a")),
        __.addE("link").from_("a")
    ).next()

But as the fold() acts as a barrier, it delete the tag "a" I put on the first vertex. My workaround is as follows:

g.V().has("label1", "property1", "value1").fold().coalesce(
        __.unfold(),
        g.addV("label1").property("property1", "value1")
    ).as_("a").V().has("label2", "property2", "value2").fold().coalesce(
        __.unfold(),
        g.addV("label2").property("property2", value2)
    ).coalesce(
        __.inE("link").where(__.outV().has("label1", "property1", value1)),
        __.addE("link").from_(__.V().has("label1", "property1", value1))
    ).next()

Can I do better? This is... ugly?


Okay, the storesolution works :) But I had a problem with the first part of the last coalesce. I did this:

g.V().has("label1", "property1", "value1").fold().coalesce(
    __.unfold(),
    g.addV("label1").property("property1", "value1")
).as_("a").V().has("label2", "property2", "value2").fold().coalesce(
    __.unfold(),
    g.addV("label2").property("property2", value2)
).coalesce(
    __.inE("link").where(__.outV().where(within("a"))),
    __.addE("link").from_(select("a").unfold())
).next()

It works fine, thanks to Kelvin Lawrence :)


Solution

  • Perhaps using store instead of as will give you what you need:

    Here is a made up example using the Gremlin Console.

    gremlin> g.V().hasLabel('notyet').
    ......1>       fold().
    ......2>       coalesce(unfold(),addV('notyet')).
    ......3>       store('a').
    ......4>       V().
    ......5>       hasLabel('notyet2').
    ......6>       fold().
    ......7>       coalesce(unfold(),addV('notyet2')).
    ......8>       coalesce(__.in('link').where(within('a')),
                            addE('link').to(select('a').unfold())) 
    ==>e[61330][61329-link->61327]