Search code examples
javagraphgremlin

Merge edge based on conditional property check


My edge contains properties active and inactive. I am trying to perform add if not exists for the edge where the condition is to check if the input date falls between active and inactive dates or not.

I am getting the below error

Caused by: io.grpc.StatusRuntimeException: INVALID_ARGUMENT: Graph traversal error, message=option(onCreate) cannot override values from merge() argument: (active, 1695658399064), code=ILLEGAL_INPUT

g.mergeE(asMap(
        T.label, "ben",
        "active", lte("1695658399064"),
        "inactive", gt("1695658399064"),
        Direction.IN, Merge.inV,
        Direction.OUT, Merge.outV
    ))
    .option(Merge.onCreate, asMap(
            T.label, "ben",
            "active", 1695658399064,
            "inactive", 1995658399064,
            Direction.IN, Merge.inV,
            Direction.OUT, Merge.outV
    ))
        .option(Merge.inV, select("v1"))
        .option(Merge.outV, select("v2"))

Solution

  • The mergeE step is intended to be used when looking for exact matches. Passing in a Predicate like lte is not going to do what it appears it may. In this particular case using the older fold ... coalesce pattern is likely going to be easier.

    Using the air routes data set, we can use a query like the following to see if an edge exists where the elev property is greater than 9,500 and the incoming vertex has an ID of 56 and the outgoing vertex has an ID of 35.

    g.E().hasLabel('route').
          has('dist',gte(9500)).
          where(inV().hasId(56).and().outV().hasId(35))   
    

    When run in the Gremlin console we can see that it finds a matching edge.

    gremlin> g.E().hasLabel('route').
    ......1>       has('dist',gte(9500)).
    ......2>       where(inV().hasId(56).and().outV().hasId(35)) 
      
    ==>e[8239][35-route->56] 
    

    For the case where the edge does not exist, the fold...coalesce pattern can be used.

    g.E().hasLabel('route').
          has('dist',gte(9500)).
          where(inV().hasId(56).and().outV().hasId(35)).
          fold().
          coalesce(unfold(),addE('route').from(V(35)).to(V(56)).property('dist',9523))
    

    Any properties that need adding to both an existing edge and a new one, can be added after the coalesce step.