Find all paths between two vertices

Not sure this makes any sense, but here goes. Could someone please provide a solution to how one would avoid dead-end paths to be traversed, i.e., how can one avoid multistep traversals following .bothE().otherV() to return to self? Here's my non-working query g.V().has('lbl', 'DexpiElement').has('tagname', 'tagA') \ .emit() \ .repeat( \ bothE().has('lbl', within('HAS_CHILD', 'HAS_CONNECTION', 'HAS_NODE', 'CONNECTED_TO', 'MAIN_CONNECTED_FROM', 'MAIN_CONNECTED_TO', 'HAS_GRAPHICS')).dedup().otherV().simplePath() \ ) \ .until(has('lbl', 'DexpiElement').has('tagname', 'tagB')) \ .simplePath() \ .has('lbl', 'DexpiElementGraphic') \ .valueMap()
18 Replies
Flynnt
Flynnt16mo ago
Hi, the problem comes from the emit step placed before the repeat step. The emit step put the current traverser in the results (kind of) : this works as intended : g.addV('DexpiElement').property("tagname","tagA").as("a"). addV('DexpiElement').property("tagname","tagB").as("b"). addV('DexpiElement').property("tagname","tagC").as("c"). addV('DexpiElement').property("tagname","tagD").as("d"). addV('DexpiElement').property("tagname","tagE").as("e"). addV('DexpiElement').property("tagname","tagF").as("f"). addV('DexpiElement').property("tagname","tagG").as("g"). addV('DexpiElement').property("tagname","tagH").as("h"). addE("HAS_CHILD").from("a").to("c"). addE("HAS_CONNECTION").from("a").to("d"). addE("HAS_CHILD").from("d").to("e"). addE("HAS_CHILD").from("e").to("f"). addE("HAS_CHILD").from("f").to("g"). addE("HAS_CHILD").from("g").to("h"). addE("HAS_CHILD").from("h").to("b") gremlin> g.V().hasLabel( 'DexpiElement').has('tagname', 'tagA').as("start").repeat( both('HAS_CHILD', 'HAS_CONNECTION', 'HAS_NODE', 'CONNECTED_TO', 'MAIN_CONNECTED_FROM','MAIN_CONNECTED_TO', 'HAS_GRAPHICS').dedup().simplePath()).until(hasLabel("DexpiElement").has('tagname', 'tagB')).path().by("tagname") ==>[tagA,tagD,tagE,tagF,tagG,tagH,tagB] with the emit step before the repeat, you have all the path traversed : gremlin> g.V().hasLabel( 'DexpiElement').has('tagname', 'tagA').as("start").emit().repeat( both('HAS_CHILD', 'HAS_CONNECTION', 'HAS_NODE', 'CONNECTED_TO', 'MAIN_CONNECTED_FROM','MAIN_CONNECTED_TO', 'HAS_GRAPHICS').dedup().simplePath()).until(hasLabel("DexpiElement").has('tagname', 'tagB')).path().by("tagname") ==>[tagA] ==>[tagA,tagC] ==>[tagA,tagD] ==>[tagA,tagD,tagE] ==>[tagA,tagD,tagE,tagF] ==>[tagA,tagD,tagE,tagF,tagG] ==>[tagA,tagD,tagE,tagF,tagG,tagH] ==>[tagA,tagD,tagE,tagF,tagG,tagH,tagB]
slygren
slygren16mo ago
Perfect! Thanks a bunch
slygren
slygren16mo ago
@flynnt_1337 a followup question - is there some way to access each DexpiElement of the resulting path, add their id's to a list for then to do further traversals? got this far, but unsure how to do the within g.V().has('lbl', 'DexpiElement').has('tagname', 'A-20PSV0100') .repeat( bothE().has('lbl', within('HAS_CHILD', 'HAS_CONNECTION', 'HAS_NODE', 'CONNECTED_TO', 'MAIN_CONNECTED_FROM', 'MAIN_CONNECTED_TO')).dedup().otherV().simplePath() ) .until(has('lbl', 'DexpiElement').has('tagname', 'A-20LV0011')) .path() .unfold() .where(values('dexpi_id')) .values('dexpi_id') .fold() .as('ids') .V().has('lbl', 'DexpiElement').has('dexpi_id', within(select('ids')))
Flynnt
Flynnt16mo ago
the path step can by modulated with a "by" step. You can also unfold the path and have acces to the elements traversed (Vertex or Edges) : g.V().hasLabel( 'DexpiElement').has('tagname', 'tagA').as("start").repeat( both('HAS_CHILD', 'HAS_CONNECTION', 'HAS_NODE', 'CONNECTED_TO', 'MAIN_CONNECTED_FROM','MAIN_CONNECTED_TO', 'HAS_GRAPHICS').dedup().simplePath()).until(hasLabel("DexpiElement").has('tagname', 'tagB')).path().unfold().valueMap() ==>[tagname:[tagA]] ==>[tagname:[tagD]] ==>[tagname:[tagE]] ==>[tagname:[tagF]] ==>[tagname:[tagG]] ==>[tagname:[tagH]] ==>[tagname:[tagB]] Just be aware that in this case, the unfold will unfold all the path if there is more than one path found. After the unfold step, you can continue your traversal like you want (with the value map in the exemple)
slygren
slygren16mo ago
I get the strange part to it yes, unsure how to approach the query. What I'm aiming for is to get the path(s) between to vertices and then for each of the DexpiElements in this/these paths do do a further traversal off each of them to reach some child vertices
Flynnt
Flynnt16mo ago
the " .where(values('dexpi_id')) .values('dexpi_id') .fold() .as('ids')" is twisted. What are you wanteing to do ? so, you can just unfold after the path step
slygren
slygren16mo ago
therefore I tried to collect the ids in a list to be used in a within statement
Flynnt
Flynnt16mo ago
it will return the Vid, and you can follow the traversal no need It's already there g.V().hasLabel( 'DexpiElement').has('tagname', 'tagA').as("start").repeat( both('HAS_CHILD', 'HAS_CONNECTION', 'HAS_NODE', 'CONNECTED_TO', 'MAIN_CONNECTED_FROM','MAIN_CONNECTED_TO', 'HAS_GRAPHICS').dedup().simplePath()).until(hasLabel("DexpiElement").has('tagname', 'tagB')).path().unfold() ==>v[0] ==>v[6] ==>v[8] ==>v[10] ==>v[12] ==>v[14] ==>v[2]
slygren
slygren16mo ago
ok, got it - trying to get my head around how to interpret the outcomes of the different steps
Flynnt
Flynnt16mo ago
(exemple with a TinkerGraph) g.V().hasLabel( 'DexpiElement').has('tagname', 'tagA').as("start").repeat( both('HAS_CHILD', 'HAS_CONNECTION', 'HAS_NODE', 'CONNECTED_TO', 'MAIN_CONNECTED_FROM','MAIN_CONNECTED_TO', 'HAS_GRAPHICS').dedup().simplePath()).until(hasLabel("DexpiElement").has('tagname', 'tagB')).path().unfold().valueMap(true) ==>[id:0,label:DexpiElement,tagname:[tagA]] ==>[id:6,label:DexpiElement,tagname:[tagD]] ==>[id:8,label:DexpiElement,tagname:[tagE]] ==>[id:10,label:DexpiElement,tagname:[tagF]] ==>[id:12,label:DexpiElement,tagname:[tagG]] ==>[id:14,label:DexpiElement,tagname:[tagH]] ==>[id:2,label:DexpiElement,tagname:[tagB]]
slygren
slygren16mo ago
the unfold to path results in both vertices and edges though, any way to filter only vertices to continue on, or again no need to?
Flynnt
Flynnt16mo ago
you can filter the edges with a label filter. I'm sure that your schema is well made and that edges and Vertex dosen't share labels.
slygren
slygren16mo ago
wouldn't bet my life on it, but yes there's no sharing of labels between the two
Flynnt
Flynnt16mo ago
g.V().hasLabel( 'DexpiElement').has('tagname', 'tagA').as("start").repeat( bothE('HAS_CHILD', 'HAS_CONNECTION', 'HAS_NODE', 'CONNECTED_TO', 'MAIN_CONNECTED_FROM','MAIN_CONNECTED_TO', 'HAS_GRAPHICS').otherV().dedup().simplePath()).until(hasLabel("DexpiElement").has('tagname', 'tagB')).path().unfold() ==>v[0] ==>e[17][0-HAS_CONNECTION->6] ==>v[6] ==>e[18][6-HAS_CHILD->8] ==>v[8] ==>e[19][8-HAS_CHILD->10] ==>v[10] ==>e[20][10-HAS_CHILD->12] ==>v[12] ==>e[21][12-HAS_CHILD->14] ==>v[14] ==>e[22][14-HAS_CHILD->2] ==>v[2] gremlin> g.V().hasLabel( 'DexpiElement').has('tagname', 'tagA').as("start").repeat( bothE('HAS_CHILD', 'HAS_CONNECTION', 'HAS_NODE', 'CONNECTED_TO', 'MAIN_CONNECTED_FROM','MAIN_CONNECTED_TO', 'HAS_GRAPHICS').otherV().dedup().simplePath()).until(hasLabel("DexpiElement").has('tagname', 'tagB')).path().unfold().hasLabel("DexpiElement") ==>v[0] ==>v[6] ==>v[8] ==>v[10] ==>v[12] ==>v[14] ==>v[2]
slygren
slygren16mo ago
This seems to be working g.V().has('lbl', 'DexpiElement').has('tagname', 'tagA') .repeat( bothE().has('lbl', within('HAS_CHILD', 'HAS_CONNECTION', 'HAS_NODE', 'CONNECTED_TO', 'MAIN_CONNECTED_FROM', 'MAIN_CONNECTED_TO')).dedup().otherV().simplePath() ) .until(has('lbl', 'DexpiElement').has('tagname', 'tagB')) .path() .unfold() .has('lbl','DexpiElement') .as('e') .project('element', 'child') .by(outE().has('lbl', 'HAS_GRAPHICS').inV().has('lbl', 'DexpiElementGraphic').as('eg').select('e','eg').by('dexpi_id').by(valueMap()).fold()) .by(outE().has('lbl', 'HAS_CHILD').inV().has('lbl', 'DexpiElement').as('ce').outE().has('lbl', 'HAS_GRAPHICS').inV().has('lbl', 'DexpiElementGraphic').as('cg').select('ce','cg').by('dexpi_id').by(valueMap()).fold()) but then again, likely not optimal in any measure Anyways - thank you very much for helping out!
Flynnt
Flynnt16mo ago
Glad i could help you
slygren
slygren16mo ago
ahh, one last - you mentioned a potential issue with the first section returning multiple paths. any simple solution to that?
Flynnt
Flynnt16mo ago
it was the emit step before the repeat that provoque that. Emit pas the traverser to the next step. In your case,the traverser was emited without any filtering with the "has('lbl', 'DexpiElement').has('tagname', 'A-20LV0011')" that was used only to stop the repeat step.
Want results from more Discord servers?
Add your server