首页 > 解决方案 > 获取路径上的年龄差距产品

问题描述

给定如下图:

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'))

我想知道边缘之间P1P5由边缘引起的所有路径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

解决方案


为一些严肃的 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]

推荐阅读