Получить продукт разницы в возрасте на пути - PullRequest
1 голос
/ 05 июня 2019

Учитывая график как:

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]

Любая помощь приветствуется.

1 Ответ

1 голос
/ 05 июня 2019

Будьте готовы к серьезному гольфу 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]
...