1
votes

I want to check if the relation between two nodes exists or not. If exists I want to update the property else add new relation between specified nodes. A groovy script is used to read data from a CSV file and run the queries.

g.V().has('label_A','A').outE('to').inV().has('label_B','B').hasNext() ? g.V().has('label_A','A').outE('to').as('e').inV().has('label_B','B').select('e').property('created','existed') : g.V().has('label_A','A').as('fromV').V().has('label_B','B').as('toV').addE('to').from('fromV').to('toV').property('created','newAdded')

g.V().has('label_A','A').outE('to').inV().has('label_B','B').hasNext() is always returning false even if the relation exists between given two nodes when ran through groovy script. The same command on the gremlin console returns the expected output. Hence new relations are created always.

Also tried the following query

g.V().hasLabel('label_A','A').as('v').V().has('label_B','B').coalesce(__.inE('to').where(outV().as('v')),addE('to').from('v').property('created','newAdded')).property('created','existed')

The above query doesn't work. No relations are added.

1
Couple of suggestions and questions: 1. You can replace outE('to').inV() with out('to') 2. Are you storing label_A as a property or as a vertex label? If it is a vertex label, then your query might be incorrect. In case of vertex label, you can replace has('label_A','A') with hasLabel('A') (same for b) - Divij
label_A is not a vertex label. It is a property. As the label is reserved, I am using label_A. I am using outE('to').inV() because there may be many edges outing from A to B, C, etc. But I want to select an edge to label_B, not others - Phoenix

1 Answers

1
votes

From a pure Gremlin perspective I think you would prefer to write that traversal as:

g.V().has('label_A','A').
  outE('to').where(inV().has('label_B','B')).
  fold().
  coalesce(unfold().property('created','existed'),
           addE('to').
           from(V().has('label_A','A')).
           to(V().has('label_B','B')).
           property('created','newAdded'))

In this way it will execute in a single request/transaction rather than two separate operations. You can see it in action in the following Gremlin Console session with TinkerGraph:

gremlin> g = TinkerGraph.open().traversal()
==>graphtraversalsource[tinkergraph[vertices:0 edges:0], standard]
gremlin> g.addV().property('label_A','A').iterate()
gremlin> g.addV().property('label_B','B').iterate()
gremlin> g.V().has('label_A','A').
......1>   outE('to').where(inV().has('label_B','B')).
......2>   fold().
......3>   coalesce(unfold().property('created','existed'),
......4>            addE('to').
......5>            from(V().has('label_A','A')).
......6>            to(V().has('label_B','B')).
......7>            property('created','newAdded'))
==>e[4][0-to->2]
gremlin> g.E().elementMap()
==>[id:4,label:to,IN:[id:2,label:vertex],OUT:[id:0,label:vertex],created:newAdded]
gremlin> g.V().has('label_A','A').
......1>   outE('to').where(inV().has('label_B','B')).
......2>   fold().
......3>   coalesce(unfold().property('created','existed'),
......4>            addE('to').
......5>            from(V().has('label_A','A')).
......6>            to(V().has('label_B','B')).
......7>            property('created','newAdded'))
==>e[4][0-to->2]
gremlin> g.E().elementMap()
==>[id:4,label:to,IN:[id:2,label:vertex],OUT:[id:0,label:vertex],created:existed]

As to why your approach doesn't work in JanusGraph, it is hard to say given the information provided. Perhaps you should try to recreate my Gremlin Console session yourself with JanusGraph and see what happens. If it still doesn't work for you, you can then supply a fully failing example for JanusGraph experts to look at.