我得到了一个很小的图:
g.addV('person').property(id, 'p1').property('name', 'mark')
g.addV('person').property(id, 'p2').property('name', 'mark')
g.addV('person').property(id, 'p3').property('name', 'jack')
g.addV('person').property(id, 'p4').property('name', 'steve')
g.addE('knows').from(V('p1')).to(V('p2')).property('since', 2001)
g.addE('knows').from(V('p1')).to(V('p3')).property('since', 2010)
g.addE('knows').from(V('p2')).to(V('p3')).property('since', 2012)
g.addE('knows').from(V('p3')).to(V('p4')).property('since', 2019)
我想提交查询以满足以下两个要求:
- 获得了所有边缘的"自",其中大于2005
- 过滤这些边缘,找出
inV
是p1
的朋友
截至目前,我只能编写以下查询:
g.E().hasLabel('knows').has('since', gt(2005)).
sideEffect(
V('p1').out().aggregate('friends')).
where(inV().where(within('friends')))
查询的结果是预期的:
gremlin> g.E().hasLabel('knows').has('since', gt(2005)).
......1> sideEffect(
......2> V('p1').out().aggregate('friends')).
......3> where(inV().where(within('friends')))
==>e[26][p1-knows->p3]
==>e[27][p2-knows->p3]
问题是sideEffect
步骤运行3次,我只想运行一次。
sideEffect()
将与遍历穿过的遍历一样多次运行。您可以 profile()
遍历正在发生的事情:
gremlin> g.E().hasLabel('knows').has('since', gt(2005)).
......1> sideEffect(V('p1').out().aggregate('friends')).
......2> where(inV().where(within('friends'))).profile()
==>Traversal Metrics
Step Count Traversers Time (ms) % Dur
=============================================================================================================
TinkerGraphStep(edge,[~label.eq(knows), since.g... 3 3 0.180 10.58
TraversalSideEffectStep([TinkerGraphStep(vertex... 3 3 0.859 50.48
TinkerGraphStep(vertex,[p1]) 3 3 0.234
VertexStep(OUT,vertex) 6 6 0.134
AggregateStep(friends) 6 6 0.226
TraversalFilterStep([EdgeVertexStep(IN), Profil... 2 2 0.662 38.95
EdgeVertexStep(IN) 3 3 0.036
WherePredicateStep(within([friends])) 0.126
>TOTAL - - 1.702 -
g.E()
鉴于您的过滤器产生3个轨道,因此将三个介绍给sideEffect()
,这意味着该步骤将执行3次。要使它执行后,一旦您需要减少3到1-您可以使用fold()
进行此操作,这将收集三个列表,然后在sideEffect()
之后展开该列表:
gremlin> g.E().hasLabel('knows').has('since', gt(2005)).
......1> fold().
......2> sideEffect(V('p1').out().aggregate('friends')).
......3> unfold().
......4> where(inV().where(within('friends'))).profile()
==>Traversal Metrics
Step Count Traversers Time (ms) % Dur
=============================================================================================================
TinkerGraphStep(edge,[~label.eq(knows), since.g... 3 3 0.203 18.23
FoldStep 1 1 0.072 6.52
TraversalSideEffectStep([TinkerGraphStep(vertex... 1 1 0.329 29.54
TinkerGraphStep(vertex,[p1]) 1 1 0.075
VertexStep(OUT,vertex) 2 2 0.061
AggregateStep(friends) 2 2 0.076
UnfoldStep 3 3 0.275 24.67
TraversalFilterStep([EdgeVertexStep(IN), Profil... 2 2 0.234 21.04
EdgeVertexStep(IN) 3 3 0.032
WherePredicateStep(within([friends])) 0.066
>TOTAL - - 1.115
所以,我认为这是您问题的直接答案。如果我要深入挖掘一点,我会想知道您是否有理由在这里描述的复杂性。如果您想找到代表" 2005年"之后的" P1"朋友的边缘的边缘,那么我认为这是通过:
来完成的。gremlin> g.V('p1').out('knows').inE('knows').has('since',gt(2005))
==>e[5][p1-knows->p3]
==>e[6][p2-knows->p3]