gremlin - 获取路径上的年龄差距产品
问题描述
给定如下图:
g.V().drop()
g.addV('Person').property(id, 'P1').property('age', 20)
g.addV('Person').property(id, 'P2').property('age', 70)
g.addV('Person').property(id, 'P3').property('age', 32)
g.addV('Person').property(id, 'P4').property('age', 50)
g.addV('Person').property(id, 'P5').property('age', 63)
g.addE('KNOWS').from(V('P1')).to(V('P2'))
g.addE('KNOWS').from(V('P2')).to(V('P3'))
g.addE('KNOWS').from(V('P3')).to(V('P4'))
g.addE('KNOWS').from(V('P4')).to(V('P5'))
g.addE('KNOWS').from(V('P2')).to(V('P5'))
g.addE('KNOWS').from(V('P3')).to(V('P5'))
我想知道边缘之间P1
和P5
由边缘引起的所有路径KNOWS
,然后计算路径上年龄差距的乘积。
到目前为止,我只能得到路径:
gremlin> g.V('P1').
......1> repeat(both('KNOWS').simplePath()).
......2> until(hasId('P5')).path()
==>[v[P1],v[P2],v[P5]]
==>[v[P1],v[P2],v[P3],v[P5]]
==>[v[P1],v[P2],v[P3],v[P4],v[P5]]
gremlin> g.V('P1').
......1> repeat(both('KNOWS').simplePath()).
......2> until(hasId('P5')).path().by("age")
==>[20,70,63]
==>[20,70,32,63]
==>[20,70,32,50,63]
为了product of age gap
明确含义,以第一个路径[20,70,63]
为例:年龄差距是[70-20, 63-70]
,即 [50, -7]
年龄差距需要为正,所以产品是50 * 7 = 350
。
预期的输出是:
==>[path: [v[P1],v[P2],v[P5]], product: 350]
==>[path: [v[P1],v[P2],v[P3],v[P5]], product: 58900]
==>[path: [v[P1],v[P2],v[P3],v[P4],v[P5]], product: 444600]
任何帮助表示赞赏。
解决方案
为一些严肃的 Gremlin 高尔夫做好准备。
g.V('P1').
repeat(both('KNOWS').simplePath()).
until(hasId('P5')).
project('path','product').
by(path()).
by(path().
by('age').
repeat(filter(count(local).is(gt(1))). /* for each pair of ages ... */
sack(assign).
by(limit(local, 1)).
skip(local, 1).
sack(minus). /* ... calculate the difference */
by(limit(local, 1))).
emit().
sack().fold(). /* fold gaps into a list and ... */
sack(assign).
by(limit(local, 1)).
skip(local, 1).
until(__.not(unfold())).
repeat(sack(mult). /* ... calculate the product */
by(limit(local, 1)).
skip(local, 1)).
choose(sack().is(lt(0)), /* make sure gaps are positive */
sack(mult).by(constant(-1))).
sack())
看起来很复杂,但主要发生了两件简单的事情。在获得年龄列表 ( path().by('age')
) 后,第一个repeat()
收集年龄之间的差距。间隙被折叠成一个新列表并传递给第二个repeat()
,然后计算产品。
在您的示例图上:
gremlin> g.V('P1').
......1> repeat(both('KNOWS').simplePath()).
......2> until(hasId('P5')).
......3> project('path','product').
......4> by(path()).
......5> by(path().
......6> by('age').
......7> repeat(filter(count(local).is(gt(1))).
......8> sack(assign).
......9> by(limit(local, 1)).
.....10> skip(local, 1).
.....11> sack(minus).
.....12> by(limit(local, 1))).
.....13> emit().
.....14> sack().fold().
.....15> sack(assign).
.....16> by(limit(local, 1)).
.....17> skip(local, 1).
.....18> until(__.not(unfold())).
.....19> repeat(sack(mult).
.....20> by(limit(local, 1)).
.....21> skip(local, 1)).
.....22> choose(sack().is(lt(0)),
.....23> sack(mult).by(constant(-1))).
.....24> sack())
==>[path:[v[P1],v[P2],v[P5]],product:350]
==>[path:[v[P1],v[P2],v[P3],v[P5]],product:58900]
==>[path:[v[P1],v[P2],v[P3],v[P4],v[P5]],product:444600]