Ranjit Soni
Ranjit Soni

Reputation: 614

How to use multiple union step in gremlin query?

I want to convert following cypher query in gremlin but facing issue while using union.

match d=(s:Group{id:123})<-[r:Member_Of*]-(p:Person) with d,
RELATIONSHIPS(d) as rels
WHERE NONE(rel in rels WHERE EXISTS(rel.`Ceased On`))
return *

UNION

match d=(s:Group{id:123})<-[r:Member_Of*]-(p:Group)-[r1:
Member_Of*]->(c:Group) with d,
RELATIONSHIPS(d) as rels
WHERE NONE(rel in rels WHERE EXISTS(rel.`Ceased On`))
return *

UNION

match d=(c:Group{id:123})-[r:Member_Of*]->(p:Group) with d,
RELATIONSHIPS(d) as rels
WHERE NONE(rel in rels WHERE EXISTS(rel.`Ceased On`))
return *

UNION

match d=(s:Group{id:123})<-[r:Member_Of*]-(p:Group)<-[r1:
Member_Of*]-(c:Person) with d,
RELATIONSHIPS(d) as rels
where NONE(rel in rels WHERE EXISTS(rel.`Ceased On`))
return *

In above cypher query, source vertex is Group, which has id '123', so for incoming and outgoing edge, I have created following gremlin query.

g.V().hasLabel('Group').has('id',123)
 union(
   __.inE('Member_Of').values('Name'), 
   __.outE('Member_Of').values('Name'))
.path()  

Now I have to traverse incoming edge for the vertex, which is incoming vertex for source vertex in above query, where I am confused with union syntax.

Please help, Thanks :)

Upvotes: 0

Views: 997

Answers (2)

Ranjit Soni
Ranjit Soni

Reputation: 614

Following is the total replacement of cypher query with gremlin query.

g.V().has('Group','id',123). //source vertex 
      union(
           //Following represent incoming Member_Of edge towards source vertex from Person Node, untill the last node in the chain
          repeat(inE('Member_Of').outV()).until(hasLabel('Person')),
          //Following represent incoming Member_Of edge from Group to source vertex and edge outwards from same Group, untill the last node in the chain
          repeat(inE('Member_Of').outV().hasLabel('Group').simplePath()).until(inE().count().is(0)).
              repeat(outE('Member_Of').inV().hasLabel('Group').simplePath()).until(inE().count().is(0)),
          //Following represent outgoing Member_Of edge from source vertex to another Group node, untill the last node in the chain
          repeat(outE('Member_Of').inV().hasLabel('Group').simplePath()).until(outE().count().is(0)),
          //Following represent incoming Member_Of edge from Group to source vertex and incoming edge from person to Group untill the last node in the chain
          repeat(inE('Member_Of').outV().hasLabel('Group').simplePath()).until(inE().count().is(0)).
              repeat(inE('Member_Of').outV().hasLabel('Person').simplePath()).until(inE().count().is(0))
      ).
      path().by(elementMap())

Upvotes: 0

Kelvin Lawrence
Kelvin Lawrence

Reputation: 14371

This part of the Cypher query

match d=(s:Group{id:123})<-[r:Member_Of*]-(p:Group)<-[r1:Member_Of*]-(c:Person)

In Gremlin, can be expressed as

g.V().has('Group','id',123).
      repeat(inE('Member_Of').outV()).until(hasLabel('G')).
      repeat(inE('Member_Of').outV()).until(hasLabel('Person')).
      path().
        by(elementMap())

If there are not really multiple hops involved (i.e. in Cypher if you do not really need the '*') you can remove the repeat construct and just keep the inE and outV steps. Anyway, this bit of Gremlin will get you the nodes and edges (relationships) along with all their properties etc. as the path will contain their elementMap.

Note that a straight port from Cypher to Gremlin may not take full advantage of the target database. For example, many Gremlin enabled stores allow user provided (real) ID values. This makes querying a lot more efficient as you can use something like this:

g.V('123')

to directly find a vertex.

Please add a comment below if this does not fully unblock you.

UPDATED: 2021-10-29

I used the air routes data set to test that the query pattern works, using this query:

g.V().has('airport','code','AUS').
      repeat(inE('contains').outV()).until(hasLabel('country')).limit(1).
      repeat(outE('contains').inV()).until(hasLabel('airport')).limit(3).
      path().
        by(elementMap())

Upvotes: 1

Related Questions