Reputation: 1
I want to make use of the sack to keep track of which vertexes have already been traversed and not continuing if the traverser encounters a vertex that is already in the list. The sack could keep a list of vertexes (either the vertex itself, or the vertex id or some other unique property like name in this case).
So here condensed to the absolute minimum: there is a starting vertex with name 'TS', it's put in the sack and then two edges are traversed, checking the reached vertex is not the starting vertex again. I tried to express it like this, but the returned paths always include path starting and ending at TS.
g.withSack([]){it.clone()}
.V()
.has('name', 'TS')
.sack{a,v->a+=v.id()}
.both()
.both()
.where(id().not(is(within(sack()))))
.path().by('name')
Same in this example, expressing a little bit more what I intend to do
g.withSack([]){it.clone()}
.V()
.has('name', 'TS')
.sack{a,v->a+=v.id()}
.repeat(
both()
.where(id().not(is(within(sack()))))
.sack{a,v->a+=v.id()}
)
.times(2)
.path().by('name')
As a side note: I know about simplePath, but this is more about keeping track of some (not all) vertexes that have been visited already - because only some vertexes will go into the sack, not all of them.
Is my query wrong or is there some erroneous reasoning and the whole idea cannot work?
Upvotes: 0
Views: 42
Reputation: 2769
Sack isn't really meant to be used this way. You're better off using something like aggregate()
or store()
.
Example query here where I have a graph of movie artists (actors/actresses) and corresponding movies they performed in:
(Artist)<-(movie)->(Artist)
Say I wanted to find all movies that Kevin Bacon and actors up to two hops away also performed in, where the runtime of the movie was less than 45 minutes:
g.V().hasLabel('Artist').has('name','Kevin Bacon').
repeat(
in('actor','actress').
sideEffect(where(values('runtime').is(lte(45))).aggregate('shortshows')).
out('actor','actress').simplePath()
).times(2).cap('shortshows').
select('shortshows').unfold().dedup().valueMap()
Which returns:
1 {'title': ['The Big Green'], 'year': [2014], 'runtime': [32]}
2 {'title': ['Material of the Future'], 'year': [2014], 'runtime': [41]}
3 {'title': ['California Sea Lions'], 'year': [2004], 'runtime': [45]}
4 {'title': ['Sky Island'], 'year': [2010], 'averageRating': [7.4], 'numVotes': [47], 'runtime': [27]}
5 {'title': ['To the Arctic 3D'], 'year': [2012], 'averageRating': [6.6], 'numVotes': [1006], 'runtime': [40]}
6 {'title': ['The Man Who Built Cambodia'], 'year': [2017], 'averageRating': [8.9], 'numVotes': [9], 'runtime': [35]}
7 {'title': ['Hope in Heaven'], 'year': [2005], 'averageRating': [6.7], 'numVotes': [19], 'runtime': [45]}
8 {'title': ['Herschel Hopper: New York Rabbit'], 'year': [2000], 'averageRating': [6.8], 'numVotes': [19], 'runtime': [45]}
9 {'title': ['In the Night I Remember Your Name'], 'year': [2018], 'runtime': [44]}
10 {'title': ['Stuart Davis: In Full Swing'], 'year': [2017], 'runtime': [30]}
The aggregate()
allows me to collect the results as I go. The sideEffect()
allows me to do this and not filter out paths in the traversal along the way. cap()
ensures that all of the traversals collapse back to a single traversal before then fetching the results from the aggreagate (which will be stored in a list), unfolding the list, deduping the results, and displaying all of their properties.
You don't need all that lambda-mumbo-jumbo. ;)
Upvotes: 0