Best way to find the shortest path between two nodes in Tinkerpop 3.1

I know this has been set several times, but I have not found a link to the latest version of Tinkerpop (3.1), which has many new useful functions that we can use in our workarounds.

Let's say I need to find a shortest path between nodes 3 and 4. Is this workaround?

gV(3).repeat(out()).until(id().is(4).and().simplePath()).path().limit(1) 

Here, I assume that when I execute the BFS search loop (thus, the first result is the shortest path), as it seems to be the case with the loop() function .

Also, is there a way to include a previously bound variable (using the as step) in the until step? More precisely, I try to select two nodes during a traversal, and then find the shortest path between them, for example,

 gV().match( __as('e0').out('Feedbacks').as('e1'), __as('e0').repeat(out('Meets')).until(<I reach e1>).path().<get_length>.as('len') ).select('e0', 'e1', 'len') 

Finally, as can be seen from the previous round, it is not clear to me how I can get the length of the shortest path. Using something like

 gV(3).repeat(out()).until(id().is(4).and().simplePath()).path().size() 

returns the size of the result (the number of rows returned), and

 gV(3).repeat(out()).until(id().is(4).and().simplePath()).path().by(__size()) 

returns an error.

Here's a graph I'm experimenting with if someone wants to play a little.

 graph = TinkerGraph.open() e0 = graph.addVertex(T.id, 0, label, "User", "name", "e0") e1 = graph.addVertex(T.id, 1, label, "User", "name", "e1") e2 = graph.addVertex(T.id, 2, label, "User", "name", "e2") e3 = graph.addVertex(T.id, 3, label, "User", "name", "e3") e4 = graph.addVertex(T.id, 4, label, "User", "name", "e4") e0.addEdge("Feedbacks", e2) e0.addEdge("Meets", e1) e2.addEdge("Feedbacks", e4) e2.addEdge("Meets", e4) e3.addEdge("Feedbacks", e0) e3.addEdge("Meets", e2) e4.addEdge("Feedbacks", e0) g = graph.traversal() 
+5
source share
1 answer

Here is a slightly shorter option for your shortest request:

 gV(3).repeat(out().simplePath()).until(hasId(4)).path().limit(1) 

Your assumption that the first path is always the shortest path is correct. To get the path length, you can use count(local) :

 gV(3).repeat(out().simplePath()).until(hasId(4)).path().count(local) 

UPDATE

As for your updated request, this should fix the problem:

 gV().as("e0").out("Feedbacks").as("e1").select("e0"). repeat(out("Meets")).until(where(eq("e1"))).path(). map(union(count(local), constant(-2)).sum()).as("len"). select("e0","e1","len") 

I subtract 2 from the total path length, because I think that you are only interested in the length of the path traversed by the repeat() block, and out().select() should not be included at the beginning. If this is not the case, then you can simply replace the third line with count(local).as("len"). .

+8
source

Source: https://habr.com/ru/post/1237238/


All Articles