all paths between any vertices with limit by length of path

273 views
Skip to first unread message

Sergei Sokolov

unread,
Oct 11, 2016, 9:00:15 AM10/11/16
to Gremlin-users
Hi!
I need to find all paths between all vertices in a graph with length of path less than 20.


If i know vertices and want to find all paths start at 271 and  ends at 44

g.V().has("code","271").repeat(__.outE("tsw").has("speed", "1").inV().simplePath()).until(__.has("code","44").or().loops().is(P.gt(19))).has("code","44").path();

But how I can find all path between all vertices?
I need something like
g.V().repeat(__.outE("tsw").has("speed", "1").inV().simplePath()).times(N).path(); where N in 1..19

But
g.V().repeat(__.outE("tsw").has("speed", "1").inV().simplePath()).until(__.loops().is(P.gt(19))).path();
not working.


Also my next question:
If i have speed in 1..6
how to find all paths for each speed value ?


Regards, Sergei.

HadoopMarc

unread,
Oct 11, 2016, 9:22:47 AM10/11/16
to Gremlin-users
Hi Segei,

See:

http://tinkerpop.apache.org/docs/3.2.1-SNAPSHOT/recipes/#shortest-path


Regards,   Marc


Op dinsdag 11 oktober 2016 15:00:15 UTC+2 schreef Sergei Sokolov:

Sergei Sokolov

unread,
Oct 11, 2016, 11:12:41 AM10/11/16
to Gremlin-users
Thanks for link! 
Seems I found solution 

g.V().repeat(__.outE("tsw").has("speed", "1").inV().simplePath()).emit(__.loops().is(P.lt(21))).path();

But next question still actual

If i have speed in 1..6
how to find all paths for each speed value ?


вторник, 11 октября 2016 г., 20:22:47 UTC+7 пользователь HadoopMarc написал:

Robert Dale

unread,
Oct 11, 2016, 11:22:46 AM10/11/16
to gremli...@googlegroups.com
This is one way to do it:
g.V().repeat(__.outE("tsw").has("speed",
within(['1','2','3','4','5','6']).inV().simplePath()).emit(__.loops().is(P.lt(21))).path();
> --
> You received this message because you are subscribed to the Google Groups
> "Gremlin-users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to gremlin-user...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/gremlin-users/cc084dc8-5403-477f-bff8-efc9576694c9%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



--
Robert Dale

Sergei Sokolov

unread,
Oct 12, 2016, 12:37:47 AM10/12/16
to Gremlin-users
Hi, Robert. Thank You for reply.

But i need (in path speed must be the same)  something like this 

for(s in ['1','2','3','4','5','6']){
  g.V().repeat(__.outE("tsw").has("speed", s).inV().simplePath()).emit(__.loops().is(P.lt(21))).path(); 
}

вторник, 11 октября 2016 г., 22:22:46 UTC+7 пользователь Robert Dale написал:

Daniel Kuppitz

unread,
Oct 12, 2016, 6:52:09 AM10/12/16
to gremli...@googlegroups.com
I will use the following sample graph for my traversals:

g = TinkerGraph.open().traversal()
g.addV().as("a").
  addV().as("b").
  addV().as("c").
  addE("tsw").from("a").to("b").property("speed", 1).
  addE("tsw").from("b").to("c").property("speed", 1).
  addE("tsw").from("a").to("b").property("speed", 2).
  addE("tsw").from("b").to("c").property("speed", 2).
  addE("tsw").from("a").to("b").property("speed", 3).
  addE("tsw").from("b").to("c").property("speed", 3).iterate()

The queries show how I came up with the final traversal (the only one that's interesting for you). Comments inline:

gremlin> // all paths
gremlin> g.V().repeat(outE("tsw").has("speed", within(1..10)).as("e").inV().simplePath()).emit(loops().is(lt(21))).
gremlin>   path().by().by("speed")
==>[v[0], 1, v[1]]
==>[v[0], 2, v[1]]
==>[v[0], 3, v[1]]
==>[v[0], 1, v[1], 1, v[2]]
==>[v[0], 1, v[1], 2, v[2]]
==>[v[0], 1, v[1], 3, v[2]]

==>[v[0], 2, v[1], 1, v[2]]
==>[v[0], 2, v[1], 2, v[2]]
==>[v[0], 2, v[1], 3, v[2]]
==>[v[0], 3, v[1], 1, v[2]]
==>[v[0], 3, v[1], 2, v[2]]

==>[v[0], 3, v[1], 3, v[2]]
==>[v[1], 1, v[2]]
==>[v[1], 2, v[2]]
==>[v[1], 3, v[2]]

gremlin> // collect distinct speed values for each path
gremlin> g.V().repeat(outE("tsw").has("speed", within(1..10)).as("e").inV().simplePath()).emit(loops().is(lt(21))).
gremlin>   map(select("e").unfold().values("speed").dedup().fold())
==>[1]
==>[2]
==>[3]
==>[1]
==>[1, 2]
==>[1, 3]
==>[2, 1]

==>[2]
==>[2, 3]
==>[3, 1]
==>[3, 2]

==>[3]
==>[1]
==>[2]
==>[3]

gremlin> // filter single speed values
gremlin> g.V().repeat(outE("tsw").has("speed", within(1..10)).as("e").inV().simplePath()).emit(loops().is(lt(21))).
gremlin>   map(select("e").unfold().values("speed").dedup().fold()).
gremlin>   filter(count(local).is(1))
==>[1]
==>[2]
==>[3]
==>[1]
==>[2]
==>[3]
==>[1]
==>[2]
==>[3]

gremlin> // combine all of the above
gremlin> g.V().repeat(outE("tsw").has("speed", within(1..10)).as("e").inV().simplePath()).emit(loops().is(lt(21))).
gremlin>   map(union(select("e").unfold().values("speed").dedup().fold(),
gremlin>       path().by().by("speed")).fold()).
gremlin>   filter(limit(local, 1).count(local).is(1))
==>[[1], [v[0], 1, v[1]]]
==>[[2], [v[0], 2, v[1]]]
==>[[3], [v[0], 3, v[1]]]
==>[[1], [v[0], 1, v[1], 1, v[2]]]
==>[[2], [v[0], 2, v[1], 2, v[2]]]
==>[[3], [v[0], 3, v[1], 3, v[2]]]
==>[[1], [v[1], 1, v[2]]]
==>[[2], [v[1], 2, v[2]]]
==>[[3], [v[1], 3, v[2]]]

gremlin> // group by speed
gremlin> g.V().repeat(outE("tsw").has("speed", within(1..10)).as("e").inV().simplePath()).emit(loops().is(lt(21))).
gremlin>   map(union(select("e").unfold().values("speed").dedup().fold(),
gremlin>       path().by().by("speed")).fold()).
gremlin>   filter(limit(local, 1).count(local).is(1)).
gremlin>   group().by(limit(local, 1).unfold()).by(tail(local, 1).fold()).next()
==>1=[[v[0], 1, v[1]], [v[0], 1, v[1], 1, v[2]], [v[1], 1, v[2]]]
==>2=[[v[0], 2, v[1]], [v[0], 2, v[1], 2, v[2]], [v[1], 2, v[2]]]
==>3=[[v[0], 3, v[1]], [v[0], 3, v[1], 3, v[2]], [v[1], 3, v[2]]]

Cheers,
Daniel



To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-users+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/gremlin-users/320cf50b-c33e-45da-be73-9d46b3fa586b%40googlegroups.com.

Sergei Sokolov

unread,
Oct 13, 2016, 7:34:55 AM10/13/16
to Gremlin-users
Hi, Daniel.
Thank You for help!!!!

среда, 12 октября 2016 г., 17:52:09 UTC+7 пользователь Daniel Kuppitz написал:

Sergei Sokolov

unread,
Oct 19, 2016, 1:02:30 AM10/19/16
to Gremlin-users
Hi, Daniel!
I`m trying to use this query in my project
g.V().repeat(__.outE("tsw").has("speed", P.within(speeds)).as("e").inV().simplePath()).emit(__.loops().is(P.lt(21)))
 
.map(__.union(__.select("e").unfold().values("speed").dedup().fold(), __.path()).fold())
 
.filter(__.limit(Scope.local, 1).count(Scope.local).is(1));


in groovy this code working fine, but  in java I get error:

Error:(45, 56) java: method union in class org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__ cannot be applied to given types;
  required: org.apache.tinkerpop.gremlin.process.traversal.Traversal<?,B>[]
  found: org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal<java.lang.Object,java.util.List<java.lang.Object>>,org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal<java.lang.Object,org.apache.tinkerpop.gremlin.process.traversal.Path>
  reason: inferred type does not conform to equality constraint(s)
    inferred: org.apache.tinkerpop.gremlin.process.traversal.Path
    equality constraints(s): org.apache.tinkerpop.gremlin.process.traversal.Path,java.util.List<java.lang.Object>

How to avoid this error? 
One of solution is use __.path().unfold() in union: 
.map(__.union(__.select("e").unfold().values("speed").dedup().fold(), __.path().unfold()).fold())


May be there is best solution?

Regards, Sergei.

Daniel Kuppitz

unread,
Oct 19, 2016, 4:47:14 AM10/19/16
to gremli...@googlegroups.com
One of solution is use __.path().unfold() in union

That's not a solution as it completely changes the query result. It should work if you cast the inner union traversals to non-generic instances of Traversal:

.map(__.union(
    (Traversal) __.select("e").unfold().values("speed").dedup().fold(),
    (Traversal) __.path()).fold())

Cheers,
Daniel



--
You received this message because you are subscribed to the Google Groups "Gremlin-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-users+unsubscribe@googlegroups.com.

Sergei Sokolov

unread,
Oct 20, 2016, 3:11:54 AM10/20/16
to Gremlin-users
Daniel, thank You! 
Now it`s working as expected.

Regards, Sergei.

среда, 19 октября 2016 г., 15:47:14 UTC+7 пользователь Daniel Kuppitz написал:
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-user...@googlegroups.com.

Sergei Sokolov

unread,
Oct 26, 2016, 4:34:41 AM10/26/16
to Gremlin-users
Hi, Daniel !
Seems i get new problem)

When I try to use SparkGraphComputer query not working.

I found that  __.select("e").unfold().values("speed").dedup().fold() - return emty array

//When i try use TinkerGraph - all is ok

gremlin
> graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin
> graph.io(IoCore.gryo()).readGraph('/mnt/data/graph/59f79cd3-0e27-498f-a15f-5d4b62dab387_graph.kryo')
==>null
gremlin
> g = graph.traversal()
==>graphtraversalsource[tinkergraph[vertices:4 edges:28], standard]


gremlin
> g.V().repeat(__.outE("tsw").as("e").inV().simplePath()).emit(__.loops().is(P.lt(21))).map(__.union((Traversal) __.select("e").unfold().values("speed").dedup().fold(), (Traversal) __.path()).fold())
==>[[1],[v[0],e[0][0-tsw->1],v[1]]]
==>[[1],[v[0],e[0][0-tsw->1],v[1],e[14][1-tsw->3],v[3]]]
==>[[1],[v[1],e[14][1-tsw->3],v[3]]]
==>[[2],[v[2],e[21][2-tsw->0],v[0]]]
==>[[1],[v[2],e[7][2-tsw->0],v[0]]]
==>[[2,1],[v[2],e[21][2-tsw->0],v[0],e[0][0-tsw->1],v[1]]]
==>[[1],[v[2],e[7][2-tsw->0],v[0],e[0][0-tsw->1],v[1]]]
==>[[2,1],[v[2],e[21][2-tsw->0],v[0],e[0][0-tsw->1],v[1],e[14][1-tsw->3],v[3]]]
==>[[1],[v[2],e[7][2-tsw->0],v[0],e[0][0-tsw->1],v[1],e[14][1-tsw->3],v[3]]]


//When i try use SparkGraphComputer - i get a problem

gremlin
> graph = GraphFactory.open('conf/hadoop/hadoop-gryo.properties')
==>hadoopgraph[gryoinputformat->gryooutputformat]
gremlin
> g = graph.traversal().withComputer(SparkGraphComputer)
==>graphtraversalsource[hadoopgraph[gryoinputformat->gryooutputformat], sparkgraphcomputer]
gremlin
> g.V().count()
==>4
gremlin
> g.V().repeat(__.outE("tsw").as("e").inV().simplePath()).emit(__.loops().is(P.lt(21))).map(__.union((Traversal) __.select("e").unfold().values("speed").dedup().fold(), (Traversal) __.path()).fold())
==>[[],[v[2],e[21][2-tsw->0],v[0]]]
==>[[],[v[2],e[7][2-tsw->0],v[0]]]
==>[[],[v[0],e[0][0-tsw->1],v[1]]]
==>[[],[v[1],e[14][1-tsw->3],v[3]]]
==>[[],[v[2],e[21][2-tsw->0],v[0],e[0][0-tsw->1],v[1]]]
==>[[],[v[2],e[7][2-tsw->0],v[0],e[0][0-tsw->1],v[1]]]
==>[[],[v[0],e[0][0-tsw->1],v[1],e[14][1-tsw->3],v[3]]]
==>[[],[v[2],e[21][2-tsw->0],v[0],e[0][0-tsw->1],v[1],e[14][1-tsw->3],v[3]]]
==>[[],[v[2],e[7][2-tsw->0],v[0],e[0][0-tsw->1],v[1],e[14][1-tsw->3],v[3]]]

Regerds, Sergei.
59f79cd3-0e27-498f-a15f-5d4b62dab387_graph.kryo
hadoop-gryo.properties

Daniel Kuppitz

unread,
Oct 26, 2016, 7:31:58 AM10/26/16
to gremli...@googlegroups.com
Yea, this is expected and the workarounds tend to be ugly. You'll have to store the speed values elsewhere in order to access them later. Here's the best solution I could come up with (other solution would most likely contaminate the path() results):

g.V().sideEffect(outE("tsw").group("x").by().by("speed")).
  repeat(__.outE("tsw").as("e").inV().simplePath()).emit(__.loops().is(P.lt(21))).map(
    union((Traversal) __.select("e").unfold().as("edge").select("x").unfold().where(select(keys).as("edge")).select(values).unfold().dedup().fold(),
          (Traversal) __.path()).fold())

I was actually using the modern graph to test it:

gremlin> graph = GraphFactory.open("conf/hadoop/hadoop-gryo.properties")
==>hadoopgraph[gryoinputformat->gryooutputformat]
gremlin> g = graph.traversal().withComputer(SparkGraphComputer)
==>graphtraversalsource[hadoopgraph[gryoinputformat->gryooutputformat], sparkgraphcomputer]

// original traversal: values not available
gremlin> g.V().sideEffect(outE().group("x").by().by("weight")).repeat(bothE().as("e").otherV().simplePath()).emit(__.loops().is(lt(3))).map(
           union(select("e").unfold().select("weight").dedup().fold(), path()).fold())
==>[[],[v[1],e[8][1-knows->4],v[4]]]
==>[[],[v[3],e[11][4-created->3],v[4]]]
==>[[],[v[5],e[10][4-created->5],v[4]]]
==>[[],[v[2],e[7][1-knows->2],v[1]]]
==>[[],[v[3],e[9][1-created->3],v[1]]]
==>[[],[v[4],e[8][1-knows->4],v[1]]]
==>[[],[v[3],e[12][6-created->3],v[6]]]
==>[[],[v[1],e[9][1-created->3],v[3]]]
==>[[],[v[4],e[11][4-created->3],v[3]]]
==>[[],[v[6],e[12][6-created->3],v[3]]]
==>[[],[v[4],e[10][4-created->5],v[5]]]
==>[[],[v[1],e[7][1-knows->2],v[2]]]
==>[[],[v[2],e[7][1-knows->2],v[1],e[8][1-knows->4],v[4]]]
==>[[],[v[3],e[9][1-created->3],v[1],e[8][1-knows->4],v[4]]]
==>[[],[v[1],e[9][1-created->3],v[3],e[11][4-created->3],v[4]]]
==>[[],[v[6],e[12][6-created->3],v[3],e[11][4-created->3],v[4]]]
==>[[],[v[3],e[11][4-created->3],v[4],e[8][1-knows->4],v[1]]]
==>[[],[v[5],e[10][4-created->5],v[4],e[8][1-knows->4],v[1]]]
==>[[],[v[4],e[11][4-created->3],v[3],e[9][1-created->3],v[1]]]
==>[[],[v[6],e[12][6-created->3],v[3],e[9][1-created->3],v[1]]]
==>[[],[v[1],e[9][1-created->3],v[3],e[12][6-created->3],v[6]]]
==>[[],[v[4],e[11][4-created->3],v[3],e[12][6-created->3],v[6]]]
==>[[],[v[1],e[8][1-knows->4],v[4],e[11][4-created->3],v[3]]]
==>[[],[v[5],e[10][4-created->5],v[4],e[11][4-created->3],v[3]]]
==>[[],[v[2],e[7][1-knows->2],v[1],e[9][1-created->3],v[3]]]
==>[[],[v[4],e[8][1-knows->4],v[1],e[9][1-created->3],v[3]]]
==>[[],[v[1],e[8][1-knows->4],v[4],e[10][4-created->5],v[5]]]
==>[[],[v[3],e[11][4-created->3],v[4],e[10][4-created->5],v[5]]]
==>[[],[v[3],e[9][1-created->3],v[1],e[7][1-knows->2],v[2]]]
==>[[],[v[4],e[8][1-knows->4],v[1],e[7][1-knows->2],v[2]]]

// tweaked traversal: values available
gremlin> g.V().sideEffect(outE().group("x").by().by("weight")).repeat(bothE().as("e").otherV().simplePath()).emit(__.loops().is(lt(3))).map(
           union(select("e").unfold().as("edge").select("x").unfold().where(select(keys).as("edge")).select(values).unfold().dedup().fold(), path()).fold())
==>[[1.0],[v[1],e[8][1-knows->4],v[4]]]
==>[[0.4],[v[3],e[11][4-created->3],v[4]]]
==>[[1.0],[v[5],e[10][4-created->5],v[4]]]
==>[[0.5],[v[2],e[7][1-knows->2],v[1]]]
==>[[0.4],[v[3],e[9][1-created->3],v[1]]]
==>[[1.0],[v[4],e[8][1-knows->4],v[1]]]
==>[[0.2],[v[3],e[12][6-created->3],v[6]]]
==>[[0.4],[v[1],e[9][1-created->3],v[3]]]
==>[[0.4],[v[4],e[11][4-created->3],v[3]]]
==>[[0.2],[v[6],e[12][6-created->3],v[3]]]
==>[[1.0],[v[4],e[10][4-created->5],v[5]]]
==>[[0.5],[v[1],e[7][1-knows->2],v[2]]]
==>[[0.5,1.0],[v[2],e[7][1-knows->2],v[1],e[8][1-knows->4],v[4]]]
==>[[0.4,1.0],[v[3],e[9][1-created->3],v[1],e[8][1-knows->4],v[4]]]
==>[[0.4,0.4],[v[1],e[9][1-created->3],v[3],e[11][4-created->3],v[4]]]
==>[[0.2,0.4],[v[6],e[12][6-created->3],v[3],e[11][4-created->3],v[4]]]
==>[[0.4,1.0],[v[3],e[11][4-created->3],v[4],e[8][1-knows->4],v[1]]]
==>[[1.0,1.0],[v[5],e[10][4-created->5],v[4],e[8][1-knows->4],v[1]]]
==>[[0.4,0.4],[v[4],e[11][4-created->3],v[3],e[9][1-created->3],v[1]]]
==>[[0.2,0.4],[v[6],e[12][6-created->3],v[3],e[9][1-created->3],v[1]]]
==>[[0.4,0.2],[v[1],e[9][1-created->3],v[3],e[12][6-created->3],v[6]]]
==>[[0.4,0.2],[v[4],e[11][4-created->3],v[3],e[12][6-created->3],v[6]]]
==>[[1.0,0.4],[v[1],e[8][1-knows->4],v[4],e[11][4-created->3],v[3]]]
==>[[1.0,0.4],[v[5],e[10][4-created->5],v[4],e[11][4-created->3],v[3]]]
==>[[0.5,0.4],[v[2],e[7][1-knows->2],v[1],e[9][1-created->3],v[3]]]
==>[[1.0,0.4],[v[4],e[8][1-knows->4],v[1],e[9][1-created->3],v[3]]]
==>[[1.0,1.0],[v[1],e[8][1-knows->4],v[4],e[10][4-created->5],v[5]]]
==>[[0.4,1.0],[v[3],e[11][4-created->3],v[4],e[10][4-created->5],v[5]]]
==>[[0.4,0.5],[v[3],e[9][1-created->3],v[1],e[7][1-knows->2],v[2]]]
==>[[1.0,0.5],[v[4],e[8][1-knows->4],v[1],e[7][1-knows->2],v[2]]]

Cheers,
Daniel


--
You received this message because you are subscribed to the Google Groups "Gremlin-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-users+unsubscribe@googlegroups.com.

Sergei Sokolov

unread,
Oct 26, 2016, 2:46:25 PM10/26/16
to Gremlin-users
Daniel, thank You  for help!

So,  query depends on graph implementation?
  
Seems now dedup() step not working on both  OLTP and OLAP: [[1.0,1.0],[v[1],e[8][1-knows->4],v[4],e[10][4-created->5],v[5]]] 
so i can not apply  
filter(__.limit(Scope.local, 1).count(Scope.local).is(1))  


I need solve more complex problem:
each Edge have  values:
speed - some id
departureTime - time departure from warehouse
arrivalTime - arrival time  to next  warehouse

I need find all paths, that meet conditions 
Ej.speed = Ej+1.speed
Ej.arrivalTime <= Ej+1.departureTime

where Ej and Ej+1 any Edges in path 
.. Ej->Vj+1->Ej+1...
(If i arrive to warehouse by edge with arrival time: 2016.01.01 12:00 then I can go forward using edges  with departure time that >= 2016.01.01 12:00)

May be I need use  "sack" step and store speed and arrivalTime, after that must select only edges with the same speed and departureTime >= arrivalTime ?

Can You help me with this query that working on OLPT and OLAP implementatios?

Regards Sergei.

среда, 26 октября 2016 г., 18:31:58 UTC+7 пользователь Daniel Kuppitz написал:
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-user...@googlegroups.com.

Daniel Kuppitz

unread,
Oct 26, 2016, 3:20:38 PM10/26/16
to gremli...@googlegroups.com
Seems now dedup() step not working on both  OLTP and OLAP: [[1.0,1.0],[v[1],e[8][1-knows->4],v[4],e[10][4-created->5],v[5]]] 

Wow, I didn't recognize that before. That's a bug and it seems I can't find a workaround without lambdas. With lambdas you can do:

gremlin> g.V().sideEffect(outE().group("x").by().by("weight")).repeat(bothE().as("e").otherV().simplePath()).emit(__.loops().is(lt(3))).map(
......1>     union(select("e").unfold().as("edge").select("x").unfold().where(select(keys).as("edge")).select(values).unfold().fold().map {it.get()*.get().toSet()}, path()).fold()).
......2>   filter(limit(local, 1).count(local).is(1))

==>[[0.5],[v[2],e[7][1-knows->2],v[1]]]
==>[[0.4],[v[3],e[9][1-created->3],v[1]]]
==>[[1.0],[v[4],e[8][1-knows->4],v[1]]]
==>[[0.5],[v[1],e[7][1-knows->2],v[2]]]
==>[[0.4],[v[1],e[9][1-created->3],v[3]]]
==>[[0.4],[v[4],e[11][4-created->3],v[3]]]
==>[[0.2],[v[6],e[12][6-created->3],v[3]]]
==>[[1.0],[v[1],e[8][1-knows->4],v[4]]]
==>[[0.4],[v[3],e[11][4-created->3],v[4]]]
==>[[1.0],[v[5],e[10][4-created->5],v[4]]]
==>[[1.0],[v[4],e[10][4-created->5],v[5]]]
==>[[0.2],[v[3],e[12][6-created->3],v[6]]]
==>[[0.4],[v[4],e[11][4-created->3],v[3],e[9][1-created->3],v[1]]]
==>[[1.0],[v[5],e[10][4-created->5],v[4],e[8][1-knows->4],v[1]]]
==>[[0.4],[v[1],e[9][1-created->3],v[3],e[11][4-created->3],v[4]]]
==>[[1.0],[v[1],e[8][1-knows->4],v[4],e[10][4-created->5],v[5]]]

Cheers,
Daniel


To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-users+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/gremlin-users/ccd0b896-86f6-4c62-a4d0-d5be290f5840%40googlegroups.com.

Daniel Kuppitz

unread,
Oct 27, 2016, 7:27:54 AM10/27/16
to gremli...@googlegroups.com
I found a solution that doesn't require lambdas. We just need to use project().aggregate("x") instead of group("x"):

gremlin> g.V().sideEffect(outE().project("key","value").by().by("weight").aggregate("x")).
           repeat(bothE().as("e").otherV().simplePath()).emit(__.loops().is(lt(3))).map(
             union(select("e").unfold().as("edge").select("x").unfold().where(select("key").as("edge")).select("value").unfold().dedup().fold(), path()).fold())

==>[[0.5],[v[2],e[7][1-knows->2],v[1]]]
==>[[0.4],[v[3],e[9][1-created->3],v[1]]]
==>[[1.0],[v[4],e[8][1-knows->4],v[1]]]
==>[[0.5],[v[1],e[7][1-knows->2],v[2]]]
==>[[0.4],[v[1],e[9][1-created->3],v[3]]]
==>[[0.4],[v[4],e[11][4-created->3],v[3]]]
==>[[0.2],[v[6],e[12][6-created->3],v[3]]]
==>[[1.0],[v[1],e[8][1-knows->4],v[4]]]
==>[[0.4],[v[3],e[11][4-created->3],v[4]]]
==>[[1.0],[v[5],e[10][4-created->5],v[4]]]
==>[[1.0],[v[4],e[10][4-created->5],v[5]]]
==>[[0.2],[v[3],e[12][6-created->3],v[6]]]
==>[[0.4],[v[4],e[11][4-created->3],v[3],e[9][1-created->3],v[1]]]
==>[[0.2,0.4],[v[6],e[12][6-created->3],v[3],e[9][1-created->3],v[1]]]
==>[[0.4,1.0],[v[3],e[11][4-created->3],v[4],e[8][1-knows->4],v[1]]]
==>[[1.0],[v[5],e[10][4-created->5],v[4],e[8][1-knows->4],v[1]]]
==>[[0.4,0.5],[v[3],e[9][1-created->3],v[1],e[7][1-knows->2],v[2]]]
==>[[1.0,0.5],[v[4],e[8][1-knows->4],v[1],e[7][1-knows->2],v[2]]]
==>[[0.5,0.4],[v[2],e[7][1-knows->2],v[1],e[9][1-created->3],v[3]]]
==>[[1.0,0.4],[v[4],e[8][1-knows->4],v[1],e[9][1-created->3],v[3]]]
==>[[0.5,1.0],[v[2],e[7][1-knows->2],v[1],e[8][1-knows->4],v[4]]]
==>[[0.4,1.0],[v[3],e[9][1-created->3],v[1],e[8][1-knows->4],v[4]]]
==>[[0.4],[v[1],e[9][1-created->3],v[3],e[11][4-created->3],v[4]]]
==>[[0.2,0.4],[v[6],e[12][6-created->3],v[3],e[11][4-created->3],v[4]]]
==>[[1.0],[v[1],e[8][1-knows->4],v[4],e[10][4-created->5],v[5]]]
==>[[0.4,1.0],[v[3],e[11][4-created->3],v[4],e[10][4-created->5],v[5]]]
==>[[1.0,0.4],[v[1],e[8][1-knows->4],v[4],e[11][4-created->3],v[3]]]
==>[[1.0,0.4],[v[5],e[10][4-created->5],v[4],e[11][4-created->3],v[3]]]
==>[[0.4,0.2],[v[1],e[9][1-created->3],v[3],e[12][6-created->3],v[6]]]
==>[[0.4,0.2],[v[4],e[11][4-created->3],v[3],e[12][6-created->3],v[6]]]

Cheers,
Daniel

Sergei Sokolov

unread,
Nov 2, 2016, 12:30:24 PM11/2/16
to Gremlin-users
Daniel, hello!

I`m trying to build query  and seems doing something wrong
Because old query working on Tinkergraph, but new query not working

graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin> graph.io(IoCore.gryo()).readGraph('/mnt/data/graph/00c3779b-a854-40dc-944d-dfb2bc9e31de_graph.kryo')
==>null
gremlin> g = graph.traversal()
==>graphtraversalsource[tinkergraph[vertices:20 edges:1478], standard]
gremlin> g.V().repeat(__.outE("tsw").as("e").inV().simplePath()).emit(__.loops().is(P.lt(21))).map(__.union((Traversal) __.select("e").unfold().values("speed").dedup().fold(), (Traversal) __.path()).fold()).filter(__.limit(Scope.local, 1).count(Scope.local).is(1)).count()
==>4800

I get this result in 5 seconds
but if I try

g.V().sideEffect(__.outE("tsw").project("key","value").by().by("speed").aggregate("x")).repeat(__.outE("tsw").as("e").inV().simplePath()).emit(__.loops().is(P.lt(21))).map(__.union((Traversal)__.select("e").unfold().as("edge").select("x").unfold().where(__.select("key").as("edge")).select("value").unfold().dedup().fold(), __.path()).fold()).filter(__.limit(Scope.local, 1).count(Scope.local).is(1)).count()

- seems I get infinity loop, because no answer in reasonable amount of time.

If i try new query without count() - gremlin console get first portion of results that look like the old query do.

Regards, Sergei.

Daniel Kuppitz

unread,
Nov 2, 2016, 8:26:26 PM11/2/16
to gremli...@googlegroups.com
Hi Sergei,

I just noticed a bug in the last query. Please try this:

g.V().sideEffect(__.outE("tsw").project("key","value").by().by("speed").aggregate("x")).barrier().
  repeat(__.outE("tsw").as("e").inV().simplePath()).
    emit(__.loops().is(P.lt(21))).
  map(__.union((Traversal) __.select("e").unfold().as("edge").select("x").unfold().where(__.select("key").as("edge")).select("value").unfold().dedup().fold(),
               (Traversal) __.path()).fold()).
  filter(__.limit(Scope.local, 1).count(Scope.local).is(1)).count()

Cheers,
Daniel


--
You received this message because you are subscribed to the Google Groups "Gremlin-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-users+unsubscribe@googlegroups.com.

Sergei Sokolov

unread,
Nov 2, 2016, 9:53:35 PM11/2/16
to Gremlin-users
Hi, Daniel!
I run query with barrier() step but no success, behavior it the same as without barrier().


Regards, Sergei.

четверг, 3 ноября 2016 г., 7:26:26 UTC+7 пользователь Daniel Kuppitz написал:
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-user...@googlegroups.com.

Daniel Kuppitz

unread,
Nov 2, 2016, 11:40:47 PM11/2/16
to gremli...@googlegroups.com
Can you share the kryo file so that I can try to reproduce it locally?

Cheers,
Daniel


To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-users+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/gremlin-users/f1deda8d-f3f3-4704-aca9-7bdc2e0762dc%40googlegroups.com.

Sergei Sokolov

unread,
Nov 2, 2016, 11:45:56 PM11/2/16
to Gremlin-users
Sorry, I get result but  it takes long time.

 Total count: 4800, at: 4850152 ms

Old query do it in 5000 ms.

But i need working with about 500000 records in result.

Regards, Sergei.

четверг, 3 ноября 2016 г., 8:53:35 UTC+7 пользователь Sergei Sokolov написал:

Sergei Sokolov

unread,
Nov 2, 2016, 11:51:25 PM11/2/16
to Gremlin-users
Daniel, kryo file attached.

Thank You for help!


четверг, 3 ноября 2016 г., 10:40:47 UTC+7 пользователь Daniel Kuppitz написал:
00c3779b-a854-40dc-944d-dfb2bc9e31de_graph.kryo

Sergei Sokolov

unread,
Nov 3, 2016, 1:02:52 AM11/3/16
to Gremlin-users
I`m do mistake with assumption 

I think it will be
about 2000 vertices
about K*100000000 edges
and i need produce N*100000000 paths.

Regards, Sergei.

Daniel Kuppitz

unread,
Nov 3, 2016, 10:50:10 AM11/3/16
to gremli...@googlegroups.com
The following query uses a different approach and assumes that you're only looking for paths with same-speed-edges. It cuts paths as soon as possible and thus it's much faster than the other approach.

g.V().repeat(__.outE("tsw").or(__.not(select("e")),
                               values("speed").as("s").select(last, "e").by("speed").where(eq("s"))).as("e").inV().simplePath()).emit().times(21).

  map(__.union(__.select(last, "e").by("speed").fold(), __.path()).fold())

It performs well over your sample graph (takes about ¼ second):

gremlin> clockWithResult(10) {
           g.V().repeat(__.outE("tsw").or(__.not(select("e")),
                                          values("speed").as("s").select(last, "e").by("speed").where(eq("s"))).as("e").inV().simplePath()).emit().times(21).

             map(__.union(__.select(last, "e").by("speed").fold(), __.path()).fold()).count().next()
         }
==>278.6631406
==>4800

The downsides:
  • works only if you're looking for same-speed edges
  • doesn't work in OLAP
You should also try to execute the previous traversal using SparkGraphComputer.

Cheers,
Daniel


To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-users+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/gremlin-users/0c1d0648-a269-4ab4-ac93-3e86675a1814%40googlegroups.com.

Sergei Sokolov

unread,
Nov 4, 2016, 3:40:30 AM11/4/16
to Gremlin-users
Hi, Daniel!
Last query is perfect)

But previous query not working on  SparkGraphComputer. Symptoms are the same as on TinkerGraph (long running time).

Regards, Sergei.

четверг, 3 ноября 2016 г., 21:50:10 UTC+7 пользователь Daniel Kuppitz написал:

Daniel Kuppitz

unread,
Nov 4, 2016, 8:59:49 AM11/4/16
to gremli...@googlegroups.com
Last query is perfect)

Great!
 
But previous query not working on  SparkGraphComputer. Symptoms are the same as on TinkerGraph (long running time).

Yea, I also tried that on my machine. The result was correct, but it took almost 100 minutes to get there.

Cheers,
Daniel


To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-users+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/gremlin-users/89ce600d-2514-4ca6-a1dd-935d85107848%40googlegroups.com.

Sergei Sokolov

unread,
Nov 16, 2016, 2:47:09 AM11/16/16
to Gremlin-users

Hi, Daniel!


Please, can You help to solve more complex problem:


Vertex v0 = graph.addVertex("code", "0");

Vertex v1 = graph.addVertex("code", "1");

Vertex v2 = graph.addVertex("code", "2");


v0.addEdge("tsw", v1, "speed", "1", "dayOfWeek", 1, "depTime", 10, "arrTime", 20 ); e[3]

v0.addEdge("tsw", v1, "speed", "1", "dayOfWeek", 1, "depTime", 15, "arrTime", 25 ); e[4]


v1.addEdge("tsw", v2, "speed", "1", "dayOfWeek", 1, "depTime", 35, "arrTime", 45 ); e[5]

v1.addEdge("tsw", v2, "speed", "1", "dayOfWeek", 1, "depTime", 40, "arrTime", 50 ); e[6]



g.V().repeat(__.outE("tsw").or(__.not(__.select("e")),

    __.values("speed").as("s").select(Pop.last, "e").by("speed").where(P.eq("s"))).as("e").inV().simplePath()).emit().times(20).

    map(__.union((Traversal) __.select(Pop.last, "e").by("speed").fold(),(Traversal) __.path()).fold());


This query give result:


[[1], [v[0], e[3][0-tsw->1], v[1]]]

[[1], [v[0], e[4][0-tsw->1], v[1]]]

[[1], [v[0], e[3][0-tsw->1], v[1], e[5][1-tsw->2], v[2]]]

[[1], [v[0], e[3][0-tsw->1], v[1], e[6][1-tsw->2], v[2]]]

[[1], [v[0], e[4][0-tsw->1], v[1], e[5][1-tsw->2], v[2]]]

[[1], [v[0], e[4][0-tsw->1], v[1], e[6][1-tsw->2], v[2]]]

[[1], [v[1], e[5][1-tsw->2], v[2]]]

[[1], [v[1], e[6][1-tsw->2], v[2]]]


Can I remove from result red lines?


I need check not only Ej.speed = Ej+1.speed

But take only one edge with minimal value of function:

timeAtWarehouse(Ej.dayOfWeek, Ej.arrTime, Ej+1.dayOfWeek, Ej+1.depTime)


So my condition for Ej+1 looks like:

Ej.speed = Ej+1.speed AND (timeAtWarehouse(Ej.dayOfWeek, Ej.arrTime, Ej+1.dayOfWeek, Ej+1.depTime) is minimal)


Where

timeAtWarehouse(Ej.dayOfWeek, Ej.arrTime, Ej+1.dayOfWeek, Ej+1.depTime) is function that return long value - in my case: time during that cargo stay at warehouse.


timeAtWarehouse(Ej.dayOfWeek, Ej.arrTime, Ej+1.dayOfWeek, Ej+1.depTime) for simplicity:


if(Ej.dayOfWeek == Ej+1.dayOfWeek && Ej.arrTime <= Ej+1.depTime) {

return  Ej+1.depTime - Ej.arrTime;

}else{

return 99999;

}


Seems I need on each step take Edges with the same speed and after that prepare this structure

[

[timeAtWarehouse1, Edge1],

[timeAtWarehouse2, Edge2],

[timeAtWarehouse3, Edge3]

]

Sort it by timeAtWarehouse DESC and take first?

Regards, Sergei.

Daniel Kuppitz

unread,
Nov 16, 2016, 8:53:42 AM11/16/16
to gremli...@googlegroups.com
Hi Sergei,

I think your description has a few bugs.


if(Ej.dayOfWeek == Ej+1.dayOfWeek && Ej.arrTime <= Ej+1.depTime) {

return  Ej+1.depTime - Ej.arrTime;


Really? Arrival time should be smaller than departure time? And then you want to subtract arrival from departure? This is probably supposed to be the other way: if departure time is smaller than arrival time, subtract departure from arrival. Right? Anyway, you can tweak this part if you have other requirements:

graph = TinkerGraph.open()


v0 = graph.addVertex("code", "0")
v1 = graph.addVertex("code", "1")
v2 = graph.addVertex("code", "2")

v0.addEdge("tsw", v1, "speed", "1", "dayOfWeek", 1, "depTime", 10, "arrTime", 20)
v0.addEdge("tsw", v1, "speed", "1", "dayOfWeek", 1, "depTime", 15, "arrTime", 25)
v1.addEdge("tsw", v2, "speed", "1", "dayOfWeek", 1, "depTime", 35, "arrTime", 45)
v1.addEdge("tsw", v2, "speed", "1", "dayOfWeek", 1, "depTime", 40, "arrTime", 50)

g = graph.traversal()

timeAtWarehouse = {
  def m = it.get()
  (m["dow0"] == m["dow1"] && m["dt"] <= m["at"]) ? (m["at"] - m["dt"]) : Integer.MAX_VALUE
}

ot = __.as("edge").values("dayOfWeek").as("dow0").select(last, "e").by("dayOfWeek").as("dow1").
    select("edge").values("arrTime").as("at").select(last, "e").by("depTime").as("dt").select("dow0","dow1","at","dt").map(timeAtWarehouse); []

g.V().outE("tsw").as("e").inV().emit().repeat(
     local(outE("tsw").filter(values("speed").as("s").select(last, "e").by("speed").where(eq("s"))).order().by(ot, decr).limit(1)).as("e").inV().simplePath()
  ).times(20).map(__.union(__.select(Pop.last, "e").by("speed").fold(), __.path()).fold())

The lambda is inevitable as we can't do subtractions in Gremlin.

Output:

gremlin> graph = TinkerGraph.open()

==>tinkergraph[vertices:0 edges:0]

gremlin> v0 = graph.addVertex("code", "0")
==>v[0]
gremlin> v1 = graph.addVertex("code", "1")
==>v[2]
gremlin> v2 = graph.addVertex("code", "2")
==>v[4]

gremlin> v0.addEdge("tsw", v1, "speed", "1", "dayOfWeek", 1, "depTime", 10, "arrTime", 20)
==>e[6][0-tsw->2]
gremlin> v0.addEdge("tsw", v1, "speed", "1", "dayOfWeek", 1, "depTime", 15, "arrTime", 25)
==>e[7][0-tsw->2]
gremlin> v1.addEdge("tsw", v2, "speed", "1", "dayOfWeek", 1, "depTime", 35, "arrTime", 45)
==>e[8][2-tsw->4]
gremlin> v1.addEdge("tsw", v2, "speed", "1", "dayOfWeek", 1, "depTime", 40, "arrTime", 50)
==>e[9][2-tsw->4]

gremlin> g = graph.traversal()
==>graphtraversalsource[tinkergraph[vertices:3 edges:4], standard]

gremlin> timeAtWarehouse = {
......1>   def m = it.get()
......2>   (m["dow0"] == m["dow1"] && m["dt"] <= m["at"]) ? (m["at"] - m["dt"]) : Integer.MAX_VALUE
......3> }
==>groovysh_evaluate$_run_closure1@715fb77

gremlin> ot = __.as("edge").values("dayOfWeek").as("dow0").select(last, "e").by("dayOfWeek").as("dow1").
......1>     select("edge").values("arrTime").as("at").select(last, "e").by("depTime").as("dt").select("dow0","dow1","at","dt").map(timeAtWarehouse); []

gremlin> g.V().outE("tsw").as("e").inV().emit().repeat(
......1>      local(outE("tsw").filter(values("speed").as("s").select(last, "e").by("speed").where(eq("s"))).order().by(ot, decr).limit(1)).as("e").inV().simplePath()
......2>   ).times(20).map(__.union(__.select(Pop.last, "e").by("speed").fold(), __.path()).fold())
==>[[1],[v[0],e[6][0-tsw->2],v[2]]]
==>[[1],[v[0],e[6][0-tsw->2],v[2],e[9][2-tsw->4],v[4]]]
==>[[1],[v[0],e[7][0-tsw->2],v[2]]]
==>[[1],[v[0],e[7][0-tsw->2],v[2],e[9][2-tsw->4],v[4]]]
==>[[1],[v[2],e[8][2-tsw->4],v[4]]]
==>[[1],[v[2],e[9][2-tsw->4],v[4]]]

Cheers,
Daniel


--
You received this message because you are subscribed to the Google Groups "Gremlin-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-users+unsubscribe@googlegroups.com.

Sergei Sokolov

unread,
Nov 16, 2016, 12:59:17 PM11/16/16
to Gremlin-users
Daniel, thank You!
I will try it.

In my description there is indeed a bug)) 

Each edge must have depDayOfWeek and arrDayOfWeek.

But Ej+1.depTime >=Ej.arrTime is ok. 
Ej.arrTime - it is arrival time to OfficeJ , Ej+1.depTime it is  departure time from OfficeJ.
Ej --> OfficeJ --> Ej+1 -->OfficeJ+1 

Ej.arrTime = 2016.11.21 10:00 , Ej+1.depTime = 2016.11.22 14:00 
 if  cargo arrived at 2016.11.21 10:00 to OfficeJ then it can go further at 2016.11.22 14:00

In my case schedule time defined by "day of week" and "time of a day". 
Cargo arrived Monday 12:00 and departured Tuesday 14:00. So i need calculate time between Monday 12:00 and Tuesday 14:00. 


Regards, Sergei.

Daniel Kuppitz

unread,
Nov 16, 2016, 3:52:51 PM11/16/16
to gremli...@googlegroups.com
I would use a different model and store timestamps instead of xyzDayOfWeek and xyzTime. Check this:

graph = TinkerGraph.open()
r = new Random()


v0 = graph.addVertex("code", "0")
v1 = graph.addVertex("code", "1")
v2 = graph.addVertex("code", "2")

v0.addEdge("tsw", v1, "speed", "1", "arrTime", t = r.nextInt(100), "depTime", t + r.nextInt(50))
v0.addEdge("tsw", v1, "speed", "1", "arrTime", t = r.nextInt(100), "depTime", t + r.nextInt(50))
v1.addEdge("tsw", v2, "speed", "1", "arrTime", t = r.nextInt(100), "depTime", t + r.nextInt(50))
v1.addEdge("tsw", v2, "speed", "1", "arrTime", t = r.nextInt(100))


g = graph.traversal()

timeAtWarehouse = {
  def m = it.get()
  return m["at"] - m["dt"]
}

ot = __.as("edge").values("arrTime").as("at").select(last, "e").by(coalesce(values("depTime"), constant(Integer.MAX_VALUE))).as("dt").select("at","dt").map(timeAtWarehouse); []


g.V().outE("tsw").as("e").inV().emit().repeat(
     local(outE("tsw").filter(values("speed").as("s").select(last, "e").by("speed").where(eq("s"))).order().by(ot, decr).limit(1)).as("e").inV().simplePath()
  ).times(20).map(__.union(__.select(Pop.last, "e").by("speed").fold(), __.path()).fold())

Without the previously added filter you would get:

gremlin> g.V().outE("tsw").as("e").inV().emit().repeat(
......1>      outE("tsw").filter(values("speed").as("s").select(last, "e").by("speed").where(eq("s"))).as("e").inV().simplePath()
......2>   ).times(20).map(__.union(__.select(Pop.last, "e").by("speed").fold(), __.path().by("code").by(valueMap("arrTime","depTime"))).fold())
==>[[1],[0,[depTime:19,arrTime:11],1]]
==>[[1],[0,[depTime:19,arrTime:11],1,[depTime:26,arrTime:18],2]]
==>[[1],[0,[depTime:19,arrTime:11],1,[arrTime:8],2]]
==>[[1],[0,[depTime:69,arrTime:32],1]]
==>[[1],[0,[depTime:69,arrTime:32],1,[depTime:26,arrTime:18],2]]
==>[[1],[0,[depTime:69,arrTime:32],1,[arrTime:8],2]]
==>[[1],[1,[depTime:26,arrTime:18],2]]
==>[[1],[1,[arrTime:8],2]]

With the filter you get:

gremlin> g.V().outE("tsw").as("e").inV().emit().repeat(
......1>      local(outE("tsw").filter(values("speed").as("s").select(last, "e").by("speed").where(eq("s"))).order().by(ot, decr).limit(1)).as("e").inV().simplePath()
......2>   ).times(20).map(__.union(__.select(Pop.last, "e").by("speed").fold(), __.path().by("code").by(valueMap("arrTime","depTime"))).fold())
==>[[1],[0,[depTime:19,arrTime:11],1]]
==>[[1],[0,[depTime:19,arrTime:11],1,[depTime:26,arrTime:18],2]]
==>[[1],[0,[depTime:69,arrTime:32],1]]
==>[[1],[0,[depTime:69,arrTime:32],1,[depTime:26,arrTime:18],2]]
==>[[1],[1,[depTime:26,arrTime:18],2]]
==>[[1],[1,[arrTime:8],2]]

Cheers,
Daniel


--
You received this message because you are subscribed to the Google Groups "Gremlin-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-users+unsubscribe@googlegroups.com.

Sergei Sokolov

unread,
Nov 17, 2016, 8:23:27 AM11/17/16
to Gremlin-users

Hi, Daniel!


First model with DayOfWeek and Time working but with one problem - may be reason is .times(20) - step. Because some paths (with length < 20) disappear from result if I add many Edges to graph (if i remove some Edges, this old paths come back).

I need get all paths with length <= 20, but seems it working different way.


I do some modification of timeAtWarehouse - for test it working ok, and do some changes in ot.

Function timeAtWarehouse = {

  def m = it.get()

  (m["dow0"] <= m["dow1"]) ? ((m["dow1"] - m["dow0"])*100 +(m["dt"] - m["at"])) : Integer.MAX_VALUE

}



Traversal ot = __.as("edge").values("dayOfWeek").as("dow1").

      select(Pop.last, "e").by("dayOfWeek").as("dow0").

      select("edge").values("depTime").as("dt").

      select(Pop.last, "e").by("arrTime").as("at").

      select("dow0","dow1","at","dt").map(timeAtWarehouse);


And also I modify sorting order: order().by(ot, Order.incr)



About second model that You advise:


I need both models

1. DayOfWeek and Time

2. Real DateTime.


Because we set up schedules by "days of week" and "time of a day" without real (Calendar DateTime).

For example Truck #1 departure: Monday 12:00 arrival Tuesday:16:00 (but there is no real DateTime).

And I need to see all paths in terms of Day Of Week and Time.


And after that I need second model where I will store real dateTime (i will calculate real DateTime for 30 days forward)  - as You specified


I need chek that I can go forward only if DepTime >= ArrTime. So i need filter by negative values in timeAtWarehouse  function - but it only for second model with real dateTime.


Thank You for help!
Regards, Sergei.

Sergei Sokolov

unread,
Nov 17, 2016, 8:48:09 AM11/17/16
to Gremlin-users

Daniel, I` wrong with my suggestion that problem in .times(20) - step

After removing .limit(1) from .order().by(ot, Order.incr).limit(1) - I get all needed paths but with many others.


Regards, Sergei.

Sergei Sokolov

unread,
Nov 17, 2016, 9:10:54 AM11/17/16
to Gremlin-users
I think problem in logic of query: 
I need take not 1 Edge with minimal timeAtWarehouse ".limit(1)", but 
I need group Edges by inVertex and select for each group Edge with minimal timeAtWarehouse (If Edge go to different Vertices it can pass).

Ej-->OfficeJ-->EAJ+1-->OfficeA
Ej-->OfficeJ-->EBJ+1-->OfficeB

Regards, Sergei.

Daniel Kuppitz

unread,
Nov 17, 2016, 9:52:43 AM11/17/16
to gremli...@googlegroups.com
Okay, hold on, this is getting really crazy. I think I know what you want, but it will take me some time to figure that out. I'm going to create a new sample graph later today, one that covers all the use cases, and get back to you once I have a solution.


Cheers,

Daniel



--
You received this message because you are subscribed to the Google Groups "Gremlin-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-users+unsubscribe@googlegroups.com.

Daniel Kuppitz

unread,
Nov 17, 2016, 12:00:29 PM11/17/16
to gremli...@googlegroups.com
I think I'm done.

timeAtWarehouse = { def pc ->
  def at = pc.get("curr").value("arrTime")
  def dt = pc.get("prev").property("depTime")
  // I think departure time will always be available on the previous edge, otherwise there
  // wouldn't be a new out-edge, right? If so, feel free to remove the isPresent() check.
  return dt.isPresent() ? dt.value() - at : Integer.MAX_VALUE
}

g.V().outE("tsw").as("e").inV().emit().repeat( /* Note, that there's no restriction for the first edge, as there's no previous edge with a reference departure time */
    flatMap(
      outE("tsw").filter(__.as("edge").select(last, "e").where(eq("edge")).by("speed")).
      group().by(inV()).by(project("curr","prev").by().by(select(last, "e"))).local(select(values).order(local).by(timeAtWarehouse).limit(local, 1).select("curr"))
    ).as("e").inV().simplePath()
  ).times(20).map(union(select(last, "e").by("speed"), path().by(id).by(valueMap("arrTime","depTime"))).fold())

The full script and its output are available right here: https://gist.github.com/dkuppitz/60c99aa693956b7c6e9bba4fa64e47dc

Cheers,
Daniel

Sergei Sokolov

unread,
Nov 17, 2016, 12:49:43 PM11/17/16
to Gremlin-users
Daniel, will try check it!

For any Edge depTime and arrTime  defined.

Office0-->Edge0--> .... EJ-->OfficeJ+1-->Ej+1  .... EdgeN-->OfficeN

Regards, Sergei.

пятница, 18 ноября 2016 г., 0:00:29 UTC+7 пользователь Daniel Kuppitz написал:
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-user...@googlegroups.com.

Sergei Sokolov

unread,
Nov 17, 2016, 1:12:19 PM11/17/16
to Gremlin-users
Daniel, try to use code in groovy app
I get error:
Exception in thread "main" java.lang.ClassCastException: org.apache.tinkerpop.gremlin.process.traversal.step.filter.WherePredicateStep cannot be cast to org.apache.tinkerpop.gremlin.process.traversal.step.ByModulating
at org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal$by$3.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
(at row  __.outE("tsw").filter(__.as("edge").select(Pop.last, "e").where(P.eq("edge")).by("speed")).)


GraphTraversal gp =  g.V().outE("tsw").as("e").inV().emit().repeat( /* Note, that there's no restriction for the first edge, as there's no previous edge with a reference departure time */
__.flatMap(
__.outE("tsw").filter(__.as("edge").select(Pop.last, "e").where(P.eq("edge")).by("speed")).
group().by(__.inV()).by(__.project("curr","prev").by().by(__.select(Pop.last, "e"))).local(__.select(Column.values).order(Scope.local).by(timeAtWarehouse).limit(Scope.local, 1).select("curr"))
).as("e").inV().simplePath()
).times(20).map(__.union(__.select(Pop.last, "e").by("speed"), __.path().by(T.id).by(__.valueMap("arrTime","depTime"))).fold())

But in groovy shell all is ok.

Regards, Sergei.

Daniel Kuppitz

unread,
Nov 17, 2016, 1:28:16 PM11/17/16
to gremli...@googlegroups.com
Then you app is using an older version of TinkerPop. where().by() was added recently (I don't remember which version exactly). Make your app use the same version as you have in your console and all should be good.

Cheers,
Daniel


--
You received this message because you are subscribed to the Google Groups "Gremlin-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-users+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/gremlin-users/9ea8911d-90fa-4115-8514-a670baf665f7%40googlegroups.com.

Sergei Sokolov

unread,
Nov 17, 2016, 2:23:24 PM11/17/16
to Gremlin-users
Yes in 3.2.3 it working.

Try to use in java code, but I`m not sure that timeAtWarehouse called (break point in this function not working) in groovy code the same.

Function timeAtWarehouse = new Function() {
@Override
public Long apply(Object o) {
Map m = (Map)((Traverser) o).get();
Long at = ((Edge)(m.get("curr"))).value("arrTime");
Long dt = ((Edge)(m.get("prev"))).value("depTime");
return dt!=null ? dt - at : Integer.MAX_VALUE;
}
};

GraphTraversal gp = g.V().outE("tsw").as("e").inV().emit().repeat( //* Note, that there's no restriction for the first edge, as there's no previous edge with a reference departure time *//*
      __.flatMap(
__.outE("tsw").filter(__.as("edge").select(Pop.last, "e").where(P.eq("edge")).by("speed")).
group().by(__.inV()).
by(__.project("curr","prev").
by().by(__.select(Pop.last, "e"))).
local(__.select(Column.values).order(Scope.local).by(timeAtWarehouse).limit(Scope.local, 1).select("curr"))
).as("e").inV().simplePath()
).times(20).map(__.union((Traversal) __.select(Pop.last, "e").by("speed"), (Traversal) __.path().by(T.id).by(__.valueMap("arrTime","depTime"))).fold());

result is:

[1, [0, {depTime=20, arrTime=10}, 1]]
[1, [0, {depTime=20, arrTime=10}, 1, {depTime=60, arrTime=50}, 3]]
[2, [0, {depTime=30, arrTime=20}, 1]]
[1, [0, {depTime=40, arrTime=20}, 1]]
[1, [0, {depTime=40, arrTime=20}, 1, {depTime=60, arrTime=50}, 3]]
[1, [0, {depTime=20, arrTime=10}, 2]]
[1, [0, {depTime=20, arrTime=10}, 2, {depTime=50, arrTime=40}, 3]]
[1, [1, {depTime=60, arrTime=50}, 3]]
[1, [1, {arrTime=50}, 3]]
[1, [2, {depTime=50, arrTime=40}, 3]]


Regards, Sergei.

Sergei Sokolov

unread,
Nov 17, 2016, 4:13:57 PM11/17/16
to Gremlin-users
Daniel, Sorry I'm taking so much of Your time. 
My IDE doing something wrong, now it ok.

So I 
changed timeAtWarehouse function

Function timeAtWarehouse = new Function() {
@Override
public Long apply(Object o) {
      Map m = (Map) o;

Long at = ((Edge)(m.get("curr"))).value("arrTime");
Long dt = ((Edge)(m.get("prev"))).value("depTime");
      return dt!=null ? at - dt : Integer.MAX_VALUE;
}
};

I put this edges to Graph:

v0.addEdge("tsw", v1, "speed", "1", "arrTime", 10l, "depTime", 20l);
v1.addEdge("tsw", v2, "speed", "1", "arrTime", 10l, "depTime", 20l);
v1.addEdge("tsw", v3, "speed", "1", "arrTime", 50l, "depTime", 60l);

I get 

[1, [0, {depTime=20, arrTime=10}, 1]]
[1, [0, {depTime=20, arrTime=10}, 1, {depTime=20, arrTime=10}, 2]]
[1, [1, {depTime=20, arrTime=10}, 2]]
[1, [1, {depTime=60, arrTime=50}, 3]]

But missing path: 0 -> 1 -> 3 

Regards, Sergei.

Daniel Kuppitz

unread,
Nov 17, 2016, 6:40:12 PM11/17/16
to gremli...@googlegroups.com
Hi Sergei,

first, dt can never be null in timeAtWarehouse. value("depTime") would throw an exception if the property doesn't exist. That's why I used property() instead of value()- If you're sure, that the property will always be present, use:

timeAtWarehouse = { def pc ->
  def at = pc.get("curr").value("arrTime")
  def dt = pc.get("prev").value("depTime")
  return dt - at
}

Now let's get to the missing path.... I wonder how it "worked" at all before, cause I messed up one part. Here's the correct query:

g.V().outE("tsw").as("e").inV().emit().repeat(
    flatMap(
      outE("tsw").filter(__.as("edge").select(last, "e").where(eq("edge")).by("speed")).
      group().by(inV()).by(project("curr","prev").by().by(select(last, "e")).fold()).select(values).unfold().
        order(local).by(timeAtWarehouse).limit(local, 1).select("curr")

    ).as("e").inV().simplePath()
  ).times(20).map(union(select(last, "e").by("speed"), path().by(id).by(valueMap("arrTime","depTime"))).fold())

I will also update the Gist in a minute.

Cheers,
Daniel


--
You received this message because you are subscribed to the Google Groups "Gremlin-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-users+unsubscribe@googlegroups.com.

Sergei Sokolov

unread,
Nov 17, 2016, 10:18:58 PM11/17/16
to Gremlin-users
Daniel, I think it works as expected! (will continue test it)
I could not do it without Your help.
So many techniques working together  in a single query 
(may be it can be useful for some tutorial).

Thanks a lot for Your help)

Regards, Sergei.

Daniel Kuppitz

unread,
Nov 18, 2016, 7:46:49 AM11/18/16
to gremli...@googlegroups.com
Yea, that's probably one of the craziest traversals I've ever written. Wonder if we can turn it into a recipe. If the OpenFlights dataset would contain arrival and departure times, we could use the same traversal to find an optimized route from airport A to airport B using the following rules:
  • use the same airline for each flight
  • minimize wait times at airports
Anyway, unfortunately OpenFlights doesn't provide this data, but maybe somebody else has another idea where we could reuse this query pattern?

Cheers,
Daniel


--
You received this message because you are subscribed to the Google Groups "Gremlin-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-users+unsubscribe@googlegroups.com.

Marko Rodriguez

unread,
Nov 18, 2016, 8:25:07 AM11/18/16
to gremli...@googlegroups.com
“Craziest traversal ever written” by the Küppįtž? That peeked my interest — what, in general, makes it so crazy?

Marko.
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/gremlin-users/CA%2Bf9seX5LrAJryCTy6GoBfNiA8y%3DPgfLTo82cbsfj5yamc0UVQ%40mail.gmail.com.

Daniel Kuppitz

unread,
Nov 18, 2016, 8:59:41 AM11/18/16
to gremli...@googlegroups.com
Probably the full bandwidth of features that this traversal is using. maps, flatMaps, branches, projections, jjust recently added by() modulators, lambdas, back-referencing to previously seen edges, and that all packed into an almost arbitrary length repetition. It's a shame that we didn't need side-effects, because then I wouldn't know which feature we're missing :).

Cheers,
Daniel


--
You received this message because you are subscribed to the Google Groups "Gremlin-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-users+unsubscribe@googlegroups.com.

Daniel Kuppitz

unread,
Nov 18, 2016, 11:47:14 AM11/18/16
to gremli...@googlegroups.com
Sergei,

check the Gist again, I just updated it. I've had an idea while reading A Gremlin Implementation of the Gremlin Traversal Machine (although it has not much to do with that change). I was able to get rid of the lambda and the traversal now uses sack() to do the math.

Cheers,
Daniel

Sergei Sokolov

unread,
Nov 18, 2016, 9:28:27 PM11/18/16
to Gremlin-users

Hi, Daniel !


It`s very interesting - using sack.

I have some comments for previous version of a query, so may be You will want to improve latest version (with sack) based on my comments.


1. Comments about graph model


My logic is:


Ej - Edge from airportJ to airportJ+1

Ej.depTime -  it is departure time from airport J.

Ej.arrTime - it is arrive time to airport J+1.


Flight 1  

departure from Berlin at 2016.10.20 10:00

arrival to Paris  2016.10.20 12:00


Flight2

departure from Paris at 2016.10.20 14:00

arrival to Milan  2016.10.20 15:40



Berlin -> Ebp -> Paris -> Epm->Milan


Ebp.depTime = 2016.10.20 10:00

Ebp.arrTime = 2016.10.20 12:00


Epm.depTime = 2016.10.20 14:00

Epm.arrTime = 2016.10.20 15:40


So there is conditions:

Cond0: depTime and arrTime - it is time in milliseconds by UTC.

Cond1: Ej.depTime < Ej.arrTime , fligth duration = Ej.arrTime - Ej.depTime

Cond2: Ej.arrTime <= Ej+1.depTime (I can go to next flight from Paris To Milan only if Ebp.arrTime <= Epm.depTime)



2.Comment about query:


For satisfy Cond2 we need filter all negative values  Ej+1.depTime  - Ej.arrTime

Ej -> AirportJ+1 -> Ej+1


I try to modify query to meet this condition:


Function timeAtWarehouse = new Function() {

 @Override

 public Long apply(Object o) {

    Map m = (Map) o;

    Long dt = ((Edge) (m.get("curr"))).value("depTime");

    Long at = ((Edge) (m.get("prev"))).value("arrTime");

    return (dt - at) >= 0? (dt - at) : Long.MAX_VALUE;  // Negative values will be at the end

  //of list after sorting

 }

};



Predicate checkNegativeTime  = new Predicate() {

 @Override

 public boolean test(Object o) {

    Map m = (Map)(((Traverser) o).get());

    Long dt = ((Edge) (m.get("curr"))).value("depTime");

    Long at = ((Edge) (m.get("prev"))).value("arrTime");

    return (dt - at) >= 0;

 }

};


I put filter to query:

order(local).by(timeAtWarehouse).

limit(local, 1).

filter(checkNegativeTime).

select("curr")



I`m not sure that it`s right way, but seems it working.


v0.addEdge("tsw", v1, "speed", "1", "arrTime", 10l, "depTime", 5l);

v1.addEdge("tsw", v2, "speed", "1", "arrTime", 15l, "depTime", 9l); // will be  ignored

v1.addEdge("tsw", v2, "speed", "1", "arrTime", 20l, "depTime", 17l); * will be used

v2.addEdge("tsw", v3, "speed", "1", "arrTime", 30l, "depTime", 25l);


Output:


[1, [0, {depTime=5, arrTime=10}, 1]]

[1, [0, {depTime=5, arrTime=10}, 1, {depTime=17, arrTime=20}, 2]] *

[1, [0, {depTime=5, arrTime=10}, 1, {depTime=17, arrTime=20}, 2, {depTime=25, arrTime=30}, 3]]  *

[1, [1, {depTime=9, arrTime=15}, 2]]

[1, [1, {depTime=9, arrTime=15}, 2, {depTime=25, arrTime=30}, 3]]

[1, [1, {depTime=17, arrTime=20}, 2]]

[1, [1, {depTime=17, arrTime=20}, 2, {depTime=25, arrTime=30}, 3]]

[1, [2, {depTime=25, arrTime=30}, 3]]



Regards, Sergei.

Daniel Kuppitz

unread,
Nov 19, 2016, 4:19:13 AM11/19/16
to gremli...@googlegroups.com
That's one way to do it, but I don't like that the same calculation is done twice. I would pre-calculate it and use this value. I've updated the Gist to show how it looks for the sack() solution.

Without sack(), well, that's something for you to figure out.

Cheers,
Daniel


--
You received this message because you are subscribed to the Google Groups "Gremlin-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-users+unsubscribe@googlegroups.com.

Sergei Sokolov

unread,
Nov 21, 2016, 12:34:43 PM11/21/16
to Gremlin-users
Daniel, thank You!

Will try query with sack, it look very cool!

Whether this query to work on a  SparkGraphComputer?

Regards, Sergei.

Daniel Kuppitz

unread,
Nov 21, 2016, 1:09:22 PM11/21/16
to gremli...@googlegroups.com
No. We need the arrivalTime from the previous edge. This is beyond the star graph limitation and thus will not work in OLAP.. Over the last few days I thought about how to write it in OLAP, but I honestly have no idea. The "easiest" way would probably be a custom vertex program.

Cheers,
Daniel


--
You received this message because you are subscribed to the Google Groups "Gremlin-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-users+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages