Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
523 views
in Technique[技术] by (71.8m points)

tinkerpop - How can I make complex Gremlin queries in AWS Neptune without variables?

I'm using Amazon Neptune, which does not support variables. For complex queries, however, I need to use a variable in multiple places. How can I do this without querying twice for the same data?

Here's the problem I'm trying to tackle:

Given a start Person, find Persons that the start Person is connected to by at most 3 steps via the knows relationship. Return each Person's name and email, as well as the distance (1-3).

How would I write this query in Gremlin without variables, since variables are unsupported in Neptune?

question from:https://stackoverflow.com/questions/66046510/how-can-i-make-complex-gremlin-queries-in-aws-neptune-without-variables

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I don't see any reason why you would need variables for your traversal and there are many ways you could get an answer. Assuming this graph:

g = TinkerGraph.open().traversal()
g.addV('person').property('name','A').property('age',20).as('a').
  addV('person').property('name','B').property('age',21).as('b').
  addV('person').property('name','C').property('age',22).as('c').
  addV('person').property('name','D').property('age',19).as('d').
  addV('person').property('name','E').property('age',22).as('e').
  addV('person').property('name','F').property('age',24).as('f').
  addE('next').from('a').to('b').
  addE('next').from('b').to('c').
  addE('next').from('b').to('d').
  addE('next').from('c').to('e').
  addE('next').from('d').to('e').
  addE('next').from('e').to('f').iterate()

You could do something like:

gremlin> g.V().has('person','name','A').
......1>   repeat(out().
......2>          group('m').
......3>            by(loops()).
......4>            by(valueMap('name','age').by(unfold()).fold())).
......5>     times(3).
......6>   cap('m')
==>[0:[[name:B,age:21]],1:[[name:C,age:22],[name:D,age:19]],2:[[name:E,age:22],[name:E,age:22]]]

Find a particular "person" vertex by their name, in this case "A", then repeatedly traverse out() and group those vertices you come across by loops() which is how deep you have traversed. I use valueMap() in this case to extract the properties you wanted. The times(3) is the limit to the depth of your search. Finally you cap() out the side-effect Map held in "m" from our group(). That approach was meant to just give you a bit of basic structure to how you would accomplish this. You could perhaps polish it further this way:

gremlin> g.V().has('person','name','A').
......1>   repeat(out().
......2>          group('m').
......3>            by(loops())).
......4>     times(3).
......5>   cap('m').unfold().select(values).unfold().
......6>   dedup().
......7>   valueMap('name','age').by(unfold())
==>[name:B,age:21]
==>[name:C,age:22]
==>[name:D,age:19]
==>[name:E,age:22]

The above example, extracts the values from the Map in "m", removes the duplicates with dedup() and then converts to the result you want. Maybe you don't need the Map in the first place (I just have it on my mind because of this answer actually) - you could simple store() your results as follows:

gremlin> g.V().has('person','name','A').
......1>   repeat(out().store('m')).
......2>     times(3).
......3>   cap('m').unfold().
......4>   dedup().
......5>   valueMap('name','age').by(unfold())
==>[name:B,age:21]
==>[name:C,age:22]
==>[name:D,age:19]
==>[name:E,age:22]

You might look at using something like simplePath() as well to help avoid re-traversing the same paths over and over again. You can read about that step in the Reference Documentation.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...