Neptune Gremlin weird mergeE behavior, updates vertex instead of edge

39 views Asked by At

I think there's a bug in mergeE(). Here's my setup in neptune

g.V().hasLabel('mytestlabel').drop()

g.addV('mytestlabel').property(id, 'testA').property('timestamp', 1).as('a')
.addV('mytestlabel').property(id, 'testA2').property('timestamp', 1).as('a2')
.addE('mytestlabel').from('a').to('a2').property('timestamp', 2).valueMap(true)

This generates my simple 2-node graph with an edge, output as expected is:

{<T.label: 4>: 'mytestlabel', <T.id: 1>: 'testA', 'timestamp': [1]}
{<T.label: 4>: 'mytestlabel', <T.id: 1>: 'testA2', 'timestamp': [1]}
{<T.label: 4>: 'mytestlabel', <T.id: 1>: '2cc6d009-4138-8b71-c016-6aa58927fe2f', 'timestamp': 2}}

Now, let's update the edge's timestamp

g.mergeE([(T.label):'mytestlabel', (Direction.from): 'testA', (Direction.to):'testA2'])
.option(onMatch, ['timestamp': 3]).valueMap(true)

As expected we get

{<T.label: 4>: 'mytestlabel', <T.id: 1>: '2cc6d009-4138-8b71-c016-6aa58927fe2f', 'timestamp': 3}

Let's try an incorrect merge syntax; using the cardinality single syntax for vertexes

g.mergeE([(T.label):'mytestlabel', (Direction.from): 'testA', (Direction.to):'testA2'])
.option(onMatch, sideEffect(property(single, 'timestamp', 4)
                            .property(single, 'edgelabel', 'exists'))
.constant([:])).valueMap(true)

As expected, it errors out:

Property cardinality can only be set for a Vertex but the traversal encountered NeptuneEdge for key: timestamp

Double checking our vertexes, they haven't changed:

{<T.label: 4>: 'mytestlabel', <T.id: 1>: 'testA', 'timestamp': [1]}
{<T.label: 4>: 'mytestlabel', <T.id: 1>: 'testA2', 'timestamp': [1]}

Now, let's add a .V() to the front of the incorrect merge:

g.V().mergeE([(T.label):'mytestlabel', (Direction.from): 'testA', (Direction.to):'testA2'])
.option(onMatch, sideEffect(property(single, 'timestamp', 4)
                            .property(single, 'edgelabel', 'exists'))
.constant([:])).valueMap(true)

This works! But in a weird way, our edge hasn't changed, but our vertexes have. A g.V() and g.E() gives us:

{<T.label: 4>: 'mytestlabel', <T.id: 1>: 'testA', 'edgelabel': ['exists'], 'timestamp': [4]}
{<T.label: 4>: 'mytestlabel', <T.id: 1>: 'testA2', 'edgelabel': ['exists'], 'timestamp': [4]}
{<T.label: 4>: 'mytestlabel', <T.id: 1>: '2cc6d009-4138-8b71-c016-6aa58927fe2f', 'timestamp': 3}

It also seems that this "incorrect" query executed once per node, I'm guessing because of the V(). Doing a g.V().count gave me 1280 exactly: butwhy

I've fixed my code so that I'm not doing .V().mergeE() and it works fine now, but I wanted to know what was happening; I think this is a bug? I can't think of why mergeEdge would ever update a vertex.

Originally I did .V().mergeE() since I was doing a big batch query and just left the .V() in there. I was getting performance issues (I'm guessing because it was executing per node in the graph) as well as incorrect values on my vertex+edges.

edit: If you try this incorrect syntax when the edge doesn't exist, it will create the edge with no properties other than label/id. If you have a 3 node graph (a-a2, a-a3), then it executes nodecount^2: enter image description here

0

There are 0 answers