Reputation: 614
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
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
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