我想利用 sack 来跟踪哪些顶点已经被遍历过,并且如果遍历器遇到列表中已经存在的顶点,则不再继续。 sack 可以保存一个顶点列表(可以是顶点本身,也可以是顶点 id 或其他一些独特的属性,例如本例中的名称)。
所以这里压缩为绝对最小值:有一个名为“TS”的起始顶点,将其放入麻袋中,然后遍历两条边,检查到达的顶点是否再次是起始顶点。我试图这样表达,但返回的路径总是包含以 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')
这个例子也一样,表达更多一点我打算做的事情
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')
作为旁注:我了解 simplePath,但这更多的是跟踪已经访问过的一些(不是全部)顶点 - 因为只有一些顶点会进入麻袋,而不是全部。
我的查询是否错误,或者是否有一些错误的推理并且整个想法无法实现?
Sack 并不是真的应该这样使用。 您最好使用
aggregate()
或 store()
之类的东西。
这里有一个示例查询,其中有电影艺术家(男演员/女演员)和他们表演的相应电影的图表:
(艺术家)<-(movie)->(艺术家)
假设我想找到 Kevin Bacon 和两跳以内的演员也演出过的所有电影,其中电影的运行时间少于 45 分钟:
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()
返回:
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]}
aggregate()
让我可以随时收集结果。 sideEffect()
允许我做到这一点,并且不会过滤掉沿途遍历的路径。 cap()
确保所有遍历都折叠回单个遍历,然后再从聚合中获取结果(将存储在列表中)、展开列表、对结果进行重复数据删除并显示其所有属性。
你不需要那些晦涩难懂的东西。 ;)