Reputation: 686
I am trying to create a graph where i can find all relationships with given person and list of their friends.
the problem statement my graph looks like this
bob ->friends -> jay
jay -> friends -> mack
jay -> friends - > john
mack -> friends -> trevor
given query where my original vertex is bob how can i show relation of
bob->jay->mack
bob->jay->john
if i do 3 hops it shold include relationship with mack-> trevor in result set
this is what i have this is the query i have thus far but it only produces resutls that are directly connected to bob and does not go out on otherV() as base selector and run 2 hops from connectedNode
results = g.V().has('person', 'bob').as('node').
union(
bothE().hasLabel('friend').as('edge').otherV().has('person').as('connectedNode'),
both().hasLabel('friend').dedup().as('connectedNode')
).
project('node', 'edge', 'connectedNode').
by(select('node').valueMap().unfold().dedup().fold()).
by(select('edge').valueMap().unfold().dedup().fold()).
by(select('connectedNode').valueMap().unfold().dedup().fold()).
toList()
what should be the correct way to get the results?
Upvotes: 2
Views: 184
Reputation: 46226
When asking questions about Gremlin it is best to include some sample data as a Gremlin script:
g.addV().property('person','bob').as('bob').
addV().property('person','jay').as('jay').
addV().property('person','mack').as('mack').
addV().property('person','john').as('john').
addV().property('person','trevor').as('trevor').
addE('friends').from('bob').to('jay').
addE('friends').from('jay').to('mack').
addE('friends').from('jay').to('john').
addE('friends').from('mack').to('trevor').iterate()
I think that the basics of this query are best accomplished with path()
:
gremlin> g.V().has('person','bob').out('friends').out('friends').path().by('person')
==>[bob,jay,mack]
==>[bob,jay,john]
I suppose that you have a situation where you might traverse in either direction on the "friends" edge, in which case you would probably want to use simplePath()
to filter out cycles:
gremlin> g.V().has('person','bob').both('friends').both('friends').simplePath().path().by('person')
==>[bob,jay,mack]
==>[bob,jay,john]
Perhaps an interesting case to consider is if you traverse from "jay":
gremlin> g.V().has('person','jay').both('friends').both('friends').simplePath().path().by('person')
==>[jay,mack,trevor]
In this case we can see that we don't get the "[jay,john]" path because traversing from "john" has no edges that have not already been traversed so that path is filtered. We can work around that issue with repeat()
:
gremlin> g.V().has('person','jay').repeat(both('friends').simplePath()).emit(__.not(outE())).path().by('person')
==>[jay,john]
==>[jay,mack,trevor]
The key is the emit(__.not(outE()))
where the repeat()
will only produce vertices that have no further edges to traverse.
Upvotes: 1