#gremlin
Вопрос:
Учитывая следующий набор данных:
g = TinkerGraph.open().traversal()
g.addV('UserJourney').property(id, 'Jeremy/Morn').
addV('UserJourney').property(id, 'Jeremy/Eve').
addV('UserJourney').property(id, 'Doug/Morn').
addV('JourneyStep').property(id, 'Watches').
addV('JourneyStep').property(id, 'TV').
addV('JourneyStep').property(id, 'Eats').
addV('JourneyStep').property(id, 'Eggs').
addV('JourneyStep').property(id, 'Toast').
addV('JourneyEnd').property(id, 'JourneyEnd').
addE('Jeremy/Morn').from(V('Eats')).to(V('Eggs')).
property('duration', 40).
addE('Jeremy/Morn').from(V('Eggs')).to(V('JourneyEnd')).
property('duration', 35).
addE('firstStep').from(V('Jeremy/Morn')).to(V('Eats')).
property('duration', 30).
addE('Jeremy/Eve').from(V('Eats')).to(V('Toast')).
property('duration', 25).
addE('Jeremy/Eve').from(V('Toast')).to(V('JourneyEnd')).
property('duration', 20).
addE('firstStep').from(V('Jeremy/Eve')).to(V('Eats')).
property('duration', 15).
addE('Doug/Morn').from(V('Watches')).to(V('TV')).
addE('Doug/Morn').from(V('TV')).to(V('Eats')).
addE('Doug/Morn').from(V('Eats')).to(V('Toast')).
addE('Doug/Morn').from(V('Toast')).to(V('JourneyEnd')).
addE('firstStep').from(V('Doug/Morn')).to(V('Watches')).
iterate()
Я хотел бы вернуть путь, пройденный за путешествие (Джереми/Морн, Джереми/Ева, Дуг/Морн), а также продолжительность каждого пути. А также общую продолжительность (стоимость) для каждого пути, я хотел бы знать продолжительность (стоимость) для каждого шага на пути. Затем я хотел бы заказать поездку по общему весу и вернуть 10 лучших.
Мой код до сих пор выглядит следующим образом:
g.V().hasLabel('UserJourney').as('a').out('firstStep').as('b').
repeat('r1', outE().where(eq('a')).by(label).by(id).inV()).
until(loops('r1').is(50).or().hasLabel('JourneyEnd').or().cyclicPath()).
path().
from('b').as('p').
map(unfold().coalesce(values('duration'),
constant(0.0)).sum()).as('cost').
select('cost','p').
group().by(project('k').by(select('a'))).unfold().select(values).tail(local).
order().by('cost', desc).
limit(10)
==>[cost:75.0,p:[v[Eats],e[0][Eats-Jeremy/Morn->Eggs],v[Eggs],e[1][Eggs-Jeremy/Morn->JourneyEnd],v[JourneyEnd]]]
==>[cost:45.0,p:[v[Eats],e[3][Eats-Jeremy/Eve->Toast],v[Toast],e[4][Toast-Jeremy/Eve->JourneyEnd],v[JourneyEnd]]]
==>[cost:0.0,p:[v[Watches],e[6][Watches-Doug/Morn->TV],v[TV],e[7][TV-Doug/Morn->Eats],v[Eats],e[8][Eats-Doug/Morn->Toast],v[Toast],e[9][Toast-Doug/Morn->JourneyEnd],v[JourneyEnd]]]
Это работает, но в результирующем наборе на javascript я получаю только идентификатор и метки ребер и вершин. Мне нужна метка, идентификатор и, по крайней мере, продолжительность.
Заранее благодарю вас за любую помощь
Ответ №1:
Изменение path
шага на наличие некоторых by
модуляторов позволяет указать расстояние на пути, а затем выбрать его позже.
gremlin> g.V().
......1> hasLabel('UserJourney').as('a').
......2> out('firstStep').as('b').
......3> repeat('r1', outE().where(eq('a')).by(label).by(id).inV()).
......4> until(
......5> loops('r1').is(50).or().hasLabel('JourneyEnd').or().cyclicPath()).
......6> path().from('b').as('p').
......7> by().
......8> by(valueMap(true,'duration')).
......9> map(unfold().coalesce(select('duration'), constant(0.0)).sum()).
.....10> as('cost').
.....11> select('cost', 'p').
.....12> group().by(project('k').by(select('a'))).
.....13> unfold().
.....14> select(values).
.....15> tail(local).
.....16> order().by('cost', desc).
.....17> limit(10)
==>[cost:75.0,p:[v[Eats],[id:0,label:Jeremy/Morn,duration:40],v[Eggs],[id:1,label:Je
remy/Morn,duration:35],v[JourneyEnd]]]
==>[cost:45.0,p:[v[Eats],[id:3,label:Jeremy/Eve,duration:25],v[Toast],[id:4,label:Je
remy/Eve,duration:20],v[JourneyEnd]]]
==>[cost:0.0,p:[v[Watches],[id:6,label:Doug/Morn],v[TV],[id:7,label:Doug/Morn],v[Eat
s],[id:8,label:Doug/Morn],v[Toast],[id:9,label:Doug/Morn],v[JourneyEnd]]]