When asking questions about Gremlin it is always helpful to include a script that creates your sample graph - for example:
g.addV('person').property('name','dave').as('d').
addV('person').property('name','rick').as('r').
addV('person').property('name','mavis').as('m').
addV('person').property('name','larry').as('l').
addV('course').property('name','english').as('e').
addV('course').property('name','history').as('h').
addV('grade').property('name','b').as('b').
addE('studies').from('d').to('e').
addE('studies').from('r').to('e').
addE('studies').from('m').to('h').
addE('studies').from('d').to('h').
addE('studies').from('r').to('h').
addE('isIn').from('l').to('b').
addE('isIn').from('d').to('b').iterate()
Here's a fairly direct way to get your answer:
gremlin> g.V().has('person','name','dave').as('d').
......1> out('studies','isIn').
......2> in('studies','isIn').
......3> where(neq('d')).
......4> dedup().
......5> values('name')
==>mavis
==>rick
==>larry
First you find "dave", label that step as "d" so that you can reference its contents later, then traverse out()
over the edges you want to match on and then back in()
on those same edges. At this point, you're back at "person" vertices who are in the same "grades" and "courses" as "dave", but you want to exclude "dave" vertices from the output so you use that where()
step. You might have duplicates if a "person" shares more than one "course" or "grade" with "dave" so you must dedup()
.
That's the basic algorithm, but you can get more advanced. Maybe you want to sort those "matches" by the number of things that each "person" has in common with "dave":
gremlin> g.V().has('person','name','dave').as('d').
......1> out('studies','isIn').
......2> in('studies','isIn').
......3> where(neq('d')).
......4> groupCount().
......5> by('name').
......6> order(local).
......7> by(values, decr)
==>[rick:2,mavis:1,larry:1]
"rick" has two "matches" (i.e. shares "english" and "history" classes) with "dave" and thus has the highest ranking. Note that the use of local
in the order()
step is important in that it means to sort within the current traverser (i.e. the Map
of name/count) - without that designation the sort would be applied to the objects in the traversal stream itself.