Warm tip: This article is reproduced from serverfault.com, please click

Edge with id already exists

发布于 2020-12-01 08:05:21

I am using the following to upsert an edge using Gremlin. I am following the recipe as mentioned here. This is the code I am using. The code runs in a lambda which talks to a cluster hosted in Amazon Neptune

    public void createEdge(final String id, final String label, final String fromId, final String toId, final Map<String, String> properties) {
        this.graphTraversalSource
            .V(fromId) // get vertex of id given for the source
            .as("fromVertex") // label as fromVertex to be accessed later
            .V(toId) // get  vertex of id given for destination
            .coalesce( // evaluates the provided traversals in order and returns the first traversal that emits at least one element
                inE(label) // check incoming edge of label given
                    .has(T.id, id) // also check for incoming edge of given ID
                    .where( // conditional check to check if edge exists
                        outV() // get destination vertex of the edge to check
                            .as("fromVertex")), // against staged vertex
                addE(label) // add edge if not present
                    .property(T.id, id) // with given id
                    .from("fromVertex")) // from source vertexx
            .next(); // end traversal to commit to graph

        log.info("Created edge {} if it doesn't exists between {} and {}", id, fromId, toId);
    }

The only difference from the example recipe mentioned in the tinkerpop website is this step that I have added. In my case, I want to create multiple edges between the same vertices with same label but different ID

.has(T.id, id) // also check for incoming edge of given ID

But I am getting the following exception

Caused by: java.util.concurrent.CompletionException: org.apache.tinkerpop.gremlin.driver.exception.ResponseException: 
{
    "detailedMessage": "Edge with id already exists: 123",
    "requestId": "dce46db8-1d0a-4717-a412-ee831973b177",
    "code": "ConstraintViolationException"
}

When I run the same query in gremlin console however, the experiment succeeds. The following query, how many times I execute, is returning the same edge. But the same is not happening with remote gremlin server

g.V().has('product','id','C1').as('v1').V().has('product','id','C2').coalesce(__.inE('rel').has('id', 'E1').where(outV().as('v1')), addE('rel').property('id', 'E1').from('v1')).next()

Can someone help me with this error

Thanks

Questioner
CHID
Viewed
0
Taylor Riggan 2020-12-01 21:52:39

The query that you have above (Lambda function code) and the query that you reference at the end of your question have one primary difference. In the query at the end of your question:

g.V().has('product','id','C1').as('v1').
   V().has('product','id','C2').
      coalesce(
          __.inE('rel').has('id', 'E1').where(outV().as('v1')),  
          addE('rel').property('id', 'E1').from('v1')).
   next()

This query is using has('id','E1') to check the id of the edge, not has(T.id,...). has('id' is looking for a custom property called 'id', whereas has(T.id is looking at the actual edge ID.

Same goes for property('id'. If using (property('id', Neptune (specifically) is going to create a UUID for the T.id value for the edge when that edge is created. So you'll end up with many edges with different T.ids but the same id property.

NOTE: You only need to use the T.id notation when coding this in Python. If using the Gremlin console you would just use either has(id,"myId") or property(id,"myId"). No quotes around id.