Neo4j and Dijkstra’s SSSP

The workday is starting to wind down slowly. I have been doing some cosmetic changes and running tests on a medical storage server. No matter what you change you must always run tests to make sure all is well.

On my last post I covered Dijkstra’s algorithm for shortest path. Shortest path implies distance and not number of vertices traversed.

I am also taking a set of courses on Big Data and Machine Learning (ML) from the University of San Diego via Coursera. Every morning I get up at or before 05:00 AM and spend a couple hours studying. For me it works better to take a class with graded quizzes and assignments than to read a book and solve some of the problems (if any) at the end of each chapter.

Graphs are quite interesting. They are used by many companies in their products (e.g., Facebook, Twitter). On my last post I implemented Dijkstra’s algorithm to get the shortest paths from a root vertex. I have enhanced it to list all the shortest paths from all nodes in a graph. In addition, I added one more graph to the test code. The graph was defined for Neo4j using a CVS file as follows:

C:\>cd C:\Documents\_Coursera\_Graph Analytics for Big Data\Week_4\neo4j_module_datasets

C:\Documents\_Coursera\_Graph Analytics for Big Data\Week_4\neo4j_module_datasets>type test.csv
Source,Target,distance
A,C,3
B,D,5
C,J,2
D,E,4
E,G,4
F,A,5
G,D,1
H,J,5
L,E,8
J,F,7
D,C,3
A,L,6
C,B,7
G,P,4

I defined the same graph using an adjacency matrix and label it a_graph.png as follows:

I used Visio and created the image for the graph. The actual adjacency matrix is in the main() function in the code.

The complete code written in Java follows:

package canessa.dijkstra.shortest.path;

import java.util.HashSet;
import java.util.Stack;

/*
 *
 */
public class Soulution {
	
	/*
	 * return the unvisited vertex with the smallest know distance from the start vertex (greedy algorithm)
	 */
	static int selectUnvisitedSmallestDistance(int[][] graph, HashSet<Integer> unVisited, int[] shortestDist) {
		
		int v 			= Integer.MAX_VALUE;
		int distance 	= Integer.MAX_VALUE;
		
		// **** select unvisited vertex with smallest know distance from the start vertex ****
		for (int i = 0; i < graph.length; i++) {
			if (unVisited.contains(i) &&
				shortestDist[i] < distance) {
				v 			= i;
				distance 	= shortestDist[i];
			}
		}

		// **** clear remaining nodes (should be unreachable) ****
		if (v == Integer.MAX_VALUE) {
			
//			System.out.println("check this out v: " + v + " distance: " + distance);
//			Iterator<Integer> iter = unVisited.iterator();
//			System.out.print("unVisited: ");
//			while (iter.hasNext()) {
//				System.out.print(iter.next());
//			}
//			System.out.println();

			unVisited.clear();
		}
		
		// **** ****
		return v;
	}
	
	/*
	 * Display shortest paths from the specified root.
	 */
	static void displayShortestPaths(int root, int[] shortestDist, int[] prevVertex) {
		
		// **** ****
		for (int i = 0; i < shortestDist.length; i++) {

			// **** skip this vertex ****
			if ((i == root) ||
				(prevVertex[i] == Integer.MAX_VALUE))
				continue;

			// System.out.printf("from: %c to: %c\n", charMap[root], charMap[i]);
			
			Stack<Character> stack = new Stack<Character>();
			
			stack.push(charMap[i]);
			
			int j = i;
			do {
				
//				System.out.printf("prevVertex[%d]: %d\n", j, prevVertex[j]);
				
				stack.push(charMap[prevVertex[j]]);
				j = prevVertex[j];
			} while (j != root);
			
			
			System.out.printf("%2d : ", shortestDist[i]);
			while (!stack.isEmpty()) {
				System.out.print(stack.pop());
				if (!stack.empty())
					System.out.print(" -> ");
			}
			System.out.println();
		}
		
	}
	
	/*
	 * 
	 */
	static void shortestPath(int[][] graph, int root) {
		
//		System.out.println("graph.length: " + graph.length);		
//		System.out.println("root: " + root);
		
		HashSet<Integer> unVisited 	= new HashSet<Integer>();
		int[] shortestDist			= new int[graph.length];
		int[] prevVertex			= new int[graph.length];
		int v;
		
		// **** initialization ****
		for (int i = 0; i < graph.length; i++) {
			shortestDist[i]	= Integer.MAX_VALUE;
			prevVertex[i] 	= Integer.MAX_VALUE;
			unVisited.add(i);
		}
		shortestDist[root] = 0;

		// **** loop visiting ALL nodes in the graph ****
		do {
			
			// **** visit unvisited vertex with the smallest know distance from the start vertex ****
			v = selectUnvisitedSmallestDistance(graph, unVisited, shortestDist);

			// **** check if no more reachable nodes are left ****
			if (v == Integer.MAX_VALUE)
				continue;

			//			System.out.println("v: " + charMap[v]);

			// **** for each unvisited neighbor of the current vertex ****
			for (int i = 0; i < graph.length; i++) { // **** skip unvisited vertices **** if (!unVisited.contains(i)) continue; // **** check if this vertex is not adjacent **** if (graph[v][i] == 0) continue; // System.out.println("visiting " + charMap[v] + " -> " + charMap[i]);
				
				// **** calculate distance from the start to this vertex ****
				int distance = shortestDist[v] + graph[v][i];
				
//				System.out.println("distance: " + distance);
				
				// **** if the calculated distance of this vertex is less than the known distance ****
				if (distance < shortestDist[i]) {
			
					// ****  update shortest distance to this vertex ****
					shortestDist[i] = distance;
			
					// **** update the previous vertex with the current vertex ****
					prevVertex[i] = v;
				}
			}

			// **** remove the vertex from the unvisited set ****
			unVisited.remove(v);
		} while (unVisited.size() != 0);

//		// **** display the shortest distances ****
//		for (int i = 1; i < graph.length; i++) { // System.out.println(charMap[root] + " -> " + charMap[i] + " : " + shortestDist[i]);
//		}
		
//		// **** display the previous vertex ****
//		for (int i = 0; i < prevVertex.length && (i != root); i++) {
//			if (prevVertex[i] != Integer.MAX_VALUE)
//				System.out.printf("prevVertex[%d]: %c\n", i, charMap[prevVertex[i]]);
//		}
		
		// **** display shortest paths ****
		displayShortestPaths(root, shortestDist, prevVertex);		
	}
	
//	static char[] charMap = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M'};
	static char[] charMap = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'L', 'P'};
	//						  0    1    2    3    4    5    6    7    8    9    0    1    2 ...

	/*
	 * 
	 */
	public static void main(String[] args) {

//		// **** graph(s) ****
//		int[][] graph = new int[][] {		// simple_graph.png
//					//   A  B  C  D  E		
//						{0, 6, 0, 1, 0},	// A
//						{6, 0, 5, 2, 2},	// B
//						{0, 5, 0, 0, 5},	// C
//						{1, 2, 0, 0, 1},	// D
//						{0, 2, 5, 1, 0}		// E
//		};
		
//		int graph[][] = new int[][]	{							// small_graph.png
//			//   TO: A   B   C   D   E   F   G   H   I	 J		FROM:
//					{0,  10, 0,  0,  0,  0,  0,  0,  0,	 0 },	// A
//					{10, 0,  0,  0,  0,  0,  0,  0,  0,	 0 }, 	// B
//					{5,  15, 0,  20, 0,  0,  20, 0,  0,  0 }, 	// C
//					{5,  0,  0,  0,  0,  0,  0,  0,  0,	 0 }, 	// D
//					{0,  5,  5,  0,  0,  0,  0,  0,  0,	 0 }, 	// E
//					{0,  0,  0,  0,  20, 0,  10, 0,  0,	 5 }, 	// F
//					{0,  0,  20, 10, 0,  0,  0,  0,  0,  0 }, 	// G
//					{0,  0,  0,  0,  20, 15, 0,  0,  10, 0 }, 	// H
//					{0,  0,  0,  0,  0,  5,  0,  0,  0,  15}, 	// I
//					{0,  0,  0,  0,  0,  15, 5,  0,  0,  0 }	// J
//		}; 
		
		int graph[][] = new int[][]	{							 	// a_graph.png
			//   TO: A   B   C   D   E   F   G   H   J   L   P	 	FROM:
					{0,  0,  3,  0,  0,  0,  0,  0,  0,  6,  0}, 	// A
					{0,  0,  0,  5,  0,  0,  0,  0,  0,  0,  0}, 	// B
					{0,  7,  0,  0,  0,  0,  0,  0,  2,  0,  0}, 	// C
					{0,  0,  3,  0,  4,  0,  0,  0,  0,  0,  0}, 	// D
					{0,  0,  0,  0,  0,  0,  4,  0,  0,  0,  0}, 	// E
					{5,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}, 	// F
					{0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  4}, 	// G
					{0,  0,  0,  0,  0,  0,  0,  0,  5,  0,  0}, 	// H
					{0,  0,  0,  0,  0,  7,  0,  0,  0,  0,  0}, 	// J
					{0,  0,  0,  0,  8,  0,  0,  0,  0,  0,  0},	// L
					{0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}		// P
		}; 
				
		// **** find shortest paths ****
		for (int v = 0; v < graph.length; v++) {
			shortestPath(graph, v);
			System.out.println();
		}
	}

}

The output for the program generated by the Eclipse IDE follows:

10 : A -> C -> B
 3 : A -> C
15 : A -> C -> B -> D
14 : A -> L -> E
12 : A -> C -> J -> F
18 : A -> L -> E -> G
 5 : A -> C -> J
 6 : A -> L
22 : A -> L -> E -> G -> P

22 : B -> D -> C -> J -> F -> A
 8 : B -> D -> C
 5 : B -> D
 9 : B -> D -> E
17 : B -> D -> C -> J -> F
13 : B -> D -> E -> G
10 : B -> D -> C -> J
28 : B -> D -> C -> J -> F -> A -> L
17 : B -> D -> E -> G -> P

14 : C -> J -> F -> A
 7 : C -> B
12 : C -> B -> D
16 : C -> B -> D -> E
 9 : C -> J -> F
20 : C -> B -> D -> E -> G
 2 : C -> J
20 : C -> J -> F -> A -> L
24 : C -> B -> D -> E -> G -> P

17 : D -> C -> J -> F -> A
10 : D -> C -> B
 3 : D -> C
 4 : D -> E
12 : D -> C -> J -> F
 8 : D -> E -> G
 5 : D -> C -> J
23 : D -> C -> J -> F -> A -> L
12 : D -> E -> G -> P

22 : E -> G -> D -> C -> J -> F -> A
15 : E -> G -> D -> C -> B
 8 : E -> G -> D -> C
 5 : E -> G -> D
17 : E -> G -> D -> C -> J -> F
 4 : E -> G
10 : E -> G -> D -> C -> J
28 : E -> G -> D -> C -> J -> F -> A -> L
 8 : E -> G -> P

 5 : F -> A
15 : F -> A -> C -> B
 8 : F -> A -> C
20 : F -> A -> C -> B -> D
19 : F -> A -> L -> E
23 : F -> A -> L -> E -> G
10 : F -> A -> C -> J
11 : F -> A -> L
27 : F -> A -> L -> E -> G -> P

18 : G -> D -> C -> J -> F -> A
11 : G -> D -> C -> B
 4 : G -> D -> C
 1 : G -> D
 5 : G -> D -> E
13 : G -> D -> C -> J -> F
 6 : G -> D -> C -> J
24 : G -> D -> C -> J -> F -> A -> L
 4 : G -> P

17 : H -> J -> F -> A
27 : H -> J -> F -> A -> C -> B
20 : H -> J -> F -> A -> C
32 : H -> J -> F -> A -> C -> B -> D
31 : H -> J -> F -> A -> L -> E
12 : H -> J -> F
35 : H -> J -> F -> A -> L -> E -> G
 5 : H -> J
23 : H -> J -> F -> A -> L
39 : H -> J -> F -> A -> L -> E -> G -> P

12 : J -> F -> A
22 : J -> F -> A -> C -> B
15 : J -> F -> A -> C
27 : J -> F -> A -> C -> B -> D
26 : J -> F -> A -> L -> E
 7 : J -> F
30 : J -> F -> A -> L -> E -> G
18 : J -> F -> A -> L
34 : J -> F -> A -> L -> E -> G -> P

30 : L -> E -> G -> D -> C -> J -> F -> A
23 : L -> E -> G -> D -> C -> B
16 : L -> E -> G -> D -> C
13 : L -> E -> G -> D
 8 : L -> E
25 : L -> E -> G -> D -> C -> J -> F
12 : L -> E -> G
18 : L -> E -> G -> D -> C -> J
16 : L -> E -> G -> P

I then spent some time comparing the results generated by the program with some CYPHER scripts in order to verify the execution of the Java program. SYPHER is the scripting language for Neo4j. Not as simple as SQL but with a little practice you can become somewhat proficient in a week or so.

Following are all the runs for the CYPHER scripts and their text results. Neo4j also produces graphic output for each table. In my case I was interested in the results which matched in all cases.

MATCH (from: MyNode {Name:'A'}), (to: MyNode),
path = shortestPath((from)-[:TO*]->(to))
where to.Name <> 'A'
WITH REDUCE(dist = 0, rel in rels(path) | dist + toInt(rel.dist)) AS distance, path, from, to limit 10
RETURN from, to, path, distance order by distance desc

╒════════════╤════════════╤══════════════════════════════════════════════════════════════════════╤══════════╕
│"from"      │"to"        │"path"                                                                │"distance"│
╞════════════╪════════════╪══════════════════════════════════════════════════════════════════════╪══════════╡
│{"Name":"A"}│{"Name":"P"}│[{"Name":"A"},{"dist":"6"},{"Name":"L"},{"Name":"L"},{"dist":"8"},{"Na│22        │
│            │            │me":"E"},{"Name":"E"},{"dist":"4"},{"Name":"G"},{"Name":"G"},{"dist":"│          │
│            │            │4"},{"Name":"P"}]                                                     │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"A"}│{"Name":"G"}│[{"Name":"A"},{"dist":"6"},{"Name":"L"},{"Name":"L"},{"dist":"8"},{"Na│18        │
│            │            │me":"E"},{"Name":"E"},{"dist":"4"},{"Name":"G"}]                      │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"A"}│{"Name":"D"}│[{"Name":"A"},{"dist":"3"},{"Name":"C"},{"Name":"C"},{"dist":"7"},{"Na│15        │
│            │            │me":"B"},{"Name":"B"},{"dist":"5"},{"Name":"D"}]                      │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"A"}│{"Name":"E"}│[{"Name":"A"},{"dist":"6"},{"Name":"L"},{"Name":"L"},{"dist":"8"},{"Na│14        │
│            │            │me":"E"}]                                                             │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"A"}│{"Name":"F"}│[{"Name":"A"},{"dist":"3"},{"Name":"C"},{"Name":"C"},{"dist":"2"},{"Na│12        │
│            │            │me":"J"},{"Name":"J"},{"dist":"7"},{"Name":"F"}]                      │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"A"}│{"Name":"B"}│[{"Name":"A"},{"dist":"3"},{"Name":"C"},{"Name":"C"},{"dist":"7"},{"Na│10        │
│            │            │me":"B"}]                                                             │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"A"}│{"Name":"L"}│[{"Name":"A"},{"dist":"6"},{"Name":"L"}]                              │6         │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"A"}│{"Name":"J"}│[{"Name":"A"},{"dist":"3"},{"Name":"C"},{"Name":"C"},{"dist":"2"},{"Na│5         │
│            │            │me":"J"}]                                                             │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"A"}│{"Name":"C"}│[{"Name":"A"},{"dist":"3"},{"Name":"C"}]                              │3         │
└────────────┴────────────┴──────────────────────────────────────────────────────────────────────┴──────────┘

MATCH (from: MyNode {Name:'B'}), (to: MyNode),
path = shortestPath((from)-[:TO*]->(to))
where to.Name <> 'B'
WITH REDUCE(dist = 0, rel in rels(path) | dist + toInt(rel.dist)) AS distance, path, from, to limit 10
RETURN from, to, path, distance order by distance desc

╒════════════╤════════════╤══════════════════════════════════════════════════════════════════════╤══════════╕
│"from"      │"to"        │"path"                                                                │"distance"│
╞════════════╪════════════╪══════════════════════════════════════════════════════════════════════╪══════════╡
│{"Name":"B"}│{"Name":"L"}│[{"Name":"B"},{"dist":"5"},{"Name":"D"},{"Name":"D"},{"dist":"3"},{"Na│28        │
│            │            │me":"C"},{"Name":"C"},{"dist":"2"},{"Name":"J"},{"Name":"J"},{"dist":"│          │
│            │            │7"},{"Name":"F"},{"Name":"F"},{"dist":"5"},{"Name":"A"},{"Name":"A"},{│          │
│            │            │"dist":"6"},{"Name":"L"}]                                             │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"B"}│{"Name":"A"}│[{"Name":"B"},{"dist":"5"},{"Name":"D"},{"Name":"D"},{"dist":"3"},{"Na│22        │
│            │            │me":"C"},{"Name":"C"},{"dist":"2"},{"Name":"J"},{"Name":"J"},{"dist":"│          │
│            │            │7"},{"Name":"F"},{"Name":"F"},{"dist":"5"},{"Name":"A"}]              │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"B"}│{"Name":"F"}│[{"Name":"B"},{"dist":"5"},{"Name":"D"},{"Name":"D"},{"dist":"3"},{"Na│17        │
│            │            │me":"C"},{"Name":"C"},{"dist":"2"},{"Name":"J"},{"Name":"J"},{"dist":"│          │
│            │            │7"},{"Name":"F"}]                                                     │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"B"}│{"Name":"P"}│[{"Name":"B"},{"dist":"5"},{"Name":"D"},{"Name":"D"},{"dist":"4"},{"Na│17        │
│            │            │me":"E"},{"Name":"E"},{"dist":"4"},{"Name":"G"},{"Name":"G"},{"dist":"│          │
│            │            │4"},{"Name":"P"}]                                                     │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"B"}│{"Name":"G"}│[{"Name":"B"},{"dist":"5"},{"Name":"D"},{"Name":"D"},{"dist":"4"},{"Na│13        │
│            │            │me":"E"},{"Name":"E"},{"dist":"4"},{"Name":"G"}]                      │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"B"}│{"Name":"J"}│[{"Name":"B"},{"dist":"5"},{"Name":"D"},{"Name":"D"},{"dist":"3"},{"Na│10        │
│            │            │me":"C"},{"Name":"C"},{"dist":"2"},{"Name":"J"}]                      │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"B"}│{"Name":"E"}│[{"Name":"B"},{"dist":"5"},{"Name":"D"},{"Name":"D"},{"dist":"4"},{"Na│9         │
│            │            │me":"E"}]                                                             │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"B"}│{"Name":"C"}│[{"Name":"B"},{"dist":"5"},{"Name":"D"},{"Name":"D"},{"dist":"3"},{"Na│8         │
│            │            │me":"C"}]                                                             │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"B"}│{"Name":"D"}│[{"Name":"B"},{"dist":"5"},{"Name":"D"}]                              │5         │
└────────────┴────────────┴──────────────────────────────────────────────────────────────────────┴──────────┘

MATCH (from: MyNode {Name:'C'}), (to: MyNode),
path = shortestPath((from)-[:TO*]->(to))
where to.Name <> 'C'
WITH REDUCE(dist = 0, rel in rels(path) | dist + toInt(rel.dist)) AS distance, path, from, to limit 10
RETURN from, to, path, distance order by distance desc

╒════════════╤════════════╤══════════════════════════════════════════════════════════════════════╤══════════╕
│"from"      │"to"        │"path"                                                                │"distance"│
╞════════════╪════════════╪══════════════════════════════════════════════════════════════════════╪══════════╡
│{"Name":"C"}│{"Name":"P"}│[{"Name":"C"},{"dist":"7"},{"Name":"B"},{"Name":"B"},{"dist":"5"},{"Na│24        │
│            │            │me":"D"},{"Name":"D"},{"dist":"4"},{"Name":"E"},{"Name":"E"},{"dist":"│          │
│            │            │4"},{"Name":"G"},{"Name":"G"},{"dist":"4"},{"Name":"P"}]              │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"C"}│{"Name":"G"}│[{"Name":"C"},{"dist":"7"},{"Name":"B"},{"Name":"B"},{"dist":"5"},{"Na│20        │
│            │            │me":"D"},{"Name":"D"},{"dist":"4"},{"Name":"E"},{"Name":"E"},{"dist":"│          │
│            │            │4"},{"Name":"G"}]                                                     │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"C"}│{"Name":"L"}│[{"Name":"C"},{"dist":"2"},{"Name":"J"},{"Name":"J"},{"dist":"7"},{"Na│20        │
│            │            │me":"F"},{"Name":"F"},{"dist":"5"},{"Name":"A"},{"Name":"A"},{"dist":"│          │
│            │            │6"},{"Name":"L"}]                                                     │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"C"}│{"Name":"E"}│[{"Name":"C"},{"dist":"7"},{"Name":"B"},{"Name":"B"},{"dist":"5"},{"Na│16        │
│            │            │me":"D"},{"Name":"D"},{"dist":"4"},{"Name":"E"}]                      │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"C"}│{"Name":"A"}│[{"Name":"C"},{"dist":"2"},{"Name":"J"},{"Name":"J"},{"dist":"7"},{"Na│14        │
│            │            │me":"F"},{"Name":"F"},{"dist":"5"},{"Name":"A"}]                      │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"C"}│{"Name":"D"}│[{"Name":"C"},{"dist":"7"},{"Name":"B"},{"Name":"B"},{"dist":"5"},{"Na│12        │
│            │            │me":"D"}]                                                             │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"C"}│{"Name":"F"}│[{"Name":"C"},{"dist":"2"},{"Name":"J"},{"Name":"J"},{"dist":"7"},{"Na│9         │
│            │            │me":"F"}]                                                             │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"C"}│{"Name":"B"}│[{"Name":"C"},{"dist":"7"},{"Name":"B"}]                              │7         │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"C"}│{"Name":"J"}│[{"Name":"C"},{"dist":"2"},{"Name":"J"}]                              │2         │
└────────────┴────────────┴──────────────────────────────────────────────────────────────────────┴──────────┘

MATCH (from: MyNode {Name:'D'}), (to: MyNode),
path = shortestPath((from)-[:TO*]->(to))
where to.Name <> 'D'
WITH REDUCE(dist = 0, rel in rels(path) | dist + toInt(rel.dist)) AS distance, path, from, to limit 10
RETURN from, to, path, distance order by distance desc

╒════════════╤════════════╤══════════════════════════════════════════════════════════════════════╤══════════╕
│"from"      │"to"        │"path"                                                                │"distance"│
╞════════════╪════════════╪══════════════════════════════════════════════════════════════════════╪══════════╡
│{"Name":"D"}│{"Name":"L"}│[{"Name":"D"},{"dist":"3"},{"Name":"C"},{"Name":"C"},{"dist":"2"},{"Na│23        │
│            │            │me":"J"},{"Name":"J"},{"dist":"7"},{"Name":"F"},{"Name":"F"},{"dist":"│          │
│            │            │5"},{"Name":"A"},{"Name":"A"},{"dist":"6"},{"Name":"L"}]              │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"D"}│{"Name":"A"}│[{"Name":"D"},{"dist":"3"},{"Name":"C"},{"Name":"C"},{"dist":"2"},{"Na│17        │
│            │            │me":"J"},{"Name":"J"},{"dist":"7"},{"Name":"F"},{"Name":"F"},{"dist":"│          │
│            │            │5"},{"Name":"A"}]                                                     │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"D"}│{"Name":"F"}│[{"Name":"D"},{"dist":"3"},{"Name":"C"},{"Name":"C"},{"dist":"2"},{"Na│12        │
│            │            │me":"J"},{"Name":"J"},{"dist":"7"},{"Name":"F"}]                      │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"D"}│{"Name":"P"}│[{"Name":"D"},{"dist":"4"},{"Name":"E"},{"Name":"E"},{"dist":"4"},{"Na│12        │
│            │            │me":"G"},{"Name":"G"},{"dist":"4"},{"Name":"P"}]                      │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"D"}│{"Name":"B"}│[{"Name":"D"},{"dist":"3"},{"Name":"C"},{"Name":"C"},{"dist":"7"},{"Na│10        │
│            │            │me":"B"}]                                                             │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"D"}│{"Name":"G"}│[{"Name":"D"},{"dist":"4"},{"Name":"E"},{"Name":"E"},{"dist":"4"},{"Na│8         │
│            │            │me":"G"}]                                                             │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"D"}│{"Name":"J"}│[{"Name":"D"},{"dist":"3"},{"Name":"C"},{"Name":"C"},{"dist":"2"},{"Na│5         │
│            │            │me":"J"}]                                                             │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"D"}│{"Name":"E"}│[{"Name":"D"},{"dist":"4"},{"Name":"E"}]                              │4         │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"D"}│{"Name":"C"}│[{"Name":"D"},{"dist":"3"},{"Name":"C"}]                              │3         │
└────────────┴────────────┴──────────────────────────────────────────────────────────────────────┴──────────┘

MATCH (from: MyNode {Name:'E'}), (to: MyNode),
path = shortestPath((from)-[:TO*]->(to))
where to.Name <> 'E'
WITH REDUCE(dist = 0, rel in rels(path) | dist + toInt(rel.dist)) AS distance, path, from, to limit 10
RETURN from, to, path, distance order by distance desc

╒════════════╤════════════╤══════════════════════════════════════════════════════════════════════╤══════════╕
│"from"      │"to"        │"path"                                                                │"distance"│
╞════════════╪════════════╪══════════════════════════════════════════════════════════════════════╪══════════╡
│{"Name":"E"}│{"Name":"L"}│[{"Name":"E"},{"dist":"4"},{"Name":"G"},{"Name":"G"},{"dist":"1"},{"Na│28        │
│            │            │me":"D"},{"Name":"D"},{"dist":"3"},{"Name":"C"},{"Name":"C"},{"dist":"│          │
│            │            │2"},{"Name":"J"},{"Name":"J"},{"dist":"7"},{"Name":"F"},{"Name":"F"},{│          │
│            │            │"dist":"5"},{"Name":"A"},{"Name":"A"},{"dist":"6"},{"Name":"L"}]      │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"E"}│{"Name":"A"}│[{"Name":"E"},{"dist":"4"},{"Name":"G"},{"Name":"G"},{"dist":"1"},{"Na│22        │
│            │            │me":"D"},{"Name":"D"},{"dist":"3"},{"Name":"C"},{"Name":"C"},{"dist":"│          │
│            │            │2"},{"Name":"J"},{"Name":"J"},{"dist":"7"},{"Name":"F"},{"Name":"F"},{│          │
│            │            │"dist":"5"},{"Name":"A"}]                                             │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"E"}│{"Name":"F"}│[{"Name":"E"},{"dist":"4"},{"Name":"G"},{"Name":"G"},{"dist":"1"},{"Na│17        │
│            │            │me":"D"},{"Name":"D"},{"dist":"3"},{"Name":"C"},{"Name":"C"},{"dist":"│          │
│            │            │2"},{"Name":"J"},{"Name":"J"},{"dist":"7"},{"Name":"F"}]              │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"E"}│{"Name":"B"}│[{"Name":"E"},{"dist":"4"},{"Name":"G"},{"Name":"G"},{"dist":"1"},{"Na│15        │
│            │            │me":"D"},{"Name":"D"},{"dist":"3"},{"Name":"C"},{"Name":"C"},{"dist":"│          │
│            │            │7"},{"Name":"B"}]                                                     │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"E"}│{"Name":"J"}│[{"Name":"E"},{"dist":"4"},{"Name":"G"},{"Name":"G"},{"dist":"1"},{"Na│10        │
│            │            │me":"D"},{"Name":"D"},{"dist":"3"},{"Name":"C"},{"Name":"C"},{"dist":"│          │
│            │            │2"},{"Name":"J"}]                                                     │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"E"}│{"Name":"C"}│[{"Name":"E"},{"dist":"4"},{"Name":"G"},{"Name":"G"},{"dist":"1"},{"Na│8         │
│            │            │me":"D"},{"Name":"D"},{"dist":"3"},{"Name":"C"}]                      │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"E"}│{"Name":"P"}│[{"Name":"E"},{"dist":"4"},{"Name":"G"},{"Name":"G"},{"dist":"4"},{"Na│8         │
│            │            │me":"P"}]                                                             │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"E"}│{"Name":"D"}│[{"Name":"E"},{"dist":"4"},{"Name":"G"},{"Name":"G"},{"dist":"1"},{"Na│5         │
│            │            │me":"D"}]                                                             │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"E"}│{"Name":"G"}│[{"Name":"E"},{"dist":"4"},{"Name":"G"}]                              │4         │
└────────────┴────────────┴──────────────────────────────────────────────────────────────────────┴──────────┘

MATCH (from: MyNode {Name:'F'}), (to: MyNode),
path = shortestPath((from)-[:TO*]->(to))
where to.Name <> 'F'
WITH REDUCE(dist = 0, rel in rels(path) | dist + toInt(rel.dist)) AS distance, path, from, to limit 10
RETURN from, to, path, distance order by distance desc

╒════════════╤════════════╤══════════════════════════════════════════════════════════════════════╤══════════╕
│"from"      │"to"        │"path"                                                                │"distance"│
╞════════════╪════════════╪══════════════════════════════════════════════════════════════════════╪══════════╡
│{"Name":"F"}│{"Name":"P"}│[{"Name":"F"},{"dist":"5"},{"Name":"A"},{"Name":"A"},{"dist":"6"},{"Na│27        │
│            │            │me":"L"},{"Name":"L"},{"dist":"8"},{"Name":"E"},{"Name":"E"},{"dist":"│          │
│            │            │4"},{"Name":"G"},{"Name":"G"},{"dist":"4"},{"Name":"P"}]              │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"F"}│{"Name":"G"}│[{"Name":"F"},{"dist":"5"},{"Name":"A"},{"Name":"A"},{"dist":"6"},{"Na│23        │
│            │            │me":"L"},{"Name":"L"},{"dist":"8"},{"Name":"E"},{"Name":"E"},{"dist":"│          │
│            │            │4"},{"Name":"G"}]                                                     │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"F"}│{"Name":"D"}│[{"Name":"F"},{"dist":"5"},{"Name":"A"},{"Name":"A"},{"dist":"3"},{"Na│20        │
│            │            │me":"C"},{"Name":"C"},{"dist":"7"},{"Name":"B"},{"Name":"B"},{"dist":"│          │
│            │            │5"},{"Name":"D"}]                                                     │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"F"}│{"Name":"E"}│[{"Name":"F"},{"dist":"5"},{"Name":"A"},{"Name":"A"},{"dist":"6"},{"Na│19        │
│            │            │me":"L"},{"Name":"L"},{"dist":"8"},{"Name":"E"}]                      │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"F"}│{"Name":"B"}│[{"Name":"F"},{"dist":"5"},{"Name":"A"},{"Name":"A"},{"dist":"3"},{"Na│15        │
│            │            │me":"C"},{"Name":"C"},{"dist":"7"},{"Name":"B"}]                      │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"F"}│{"Name":"L"}│[{"Name":"F"},{"dist":"5"},{"Name":"A"},{"Name":"A"},{"dist":"6"},{"Na│11        │
│            │            │me":"L"}]                                                             │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"F"}│{"Name":"J"}│[{"Name":"F"},{"dist":"5"},{"Name":"A"},{"Name":"A"},{"dist":"3"},{"Na│10        │
│            │            │me":"C"},{"Name":"C"},{"dist":"2"},{"Name":"J"}]                      │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"F"}│{"Name":"C"}│[{"Name":"F"},{"dist":"5"},{"Name":"A"},{"Name":"A"},{"dist":"3"},{"Na│8         │
│            │            │me":"C"}]                                                             │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"F"}│{"Name":"A"}│[{"Name":"F"},{"dist":"5"},{"Name":"A"}]                              │5         │
└────────────┴────────────┴──────────────────────────────────────────────────────────────────────┴──────────┘

MATCH (from: MyNode {Name:'G'}), (to: MyNode),
path = shortestPath((from)-[:TO*]->(to))
where to.Name <> 'G'
WITH REDUCE(dist = 0, rel in rels(path) | dist + toInt(rel.dist)) AS distance, path, from, to limit 10
RETURN from, to, path, distance order by distance desc

╒════════════╤════════════╤══════════════════════════════════════════════════════════════════════╤══════════╕
│"from"      │"to"        │"path"                                                                │"distance"│
╞════════════╪════════════╪══════════════════════════════════════════════════════════════════════╪══════════╡
│{"Name":"G"}│{"Name":"L"}│[{"Name":"G"},{"dist":"1"},{"Name":"D"},{"Name":"D"},{"dist":"3"},{"Na│24        │
│            │            │me":"C"},{"Name":"C"},{"dist":"2"},{"Name":"J"},{"Name":"J"},{"dist":"│          │
│            │            │7"},{"Name":"F"},{"Name":"F"},{"dist":"5"},{"Name":"A"},{"Name":"A"},{│          │
│            │            │"dist":"6"},{"Name":"L"}]                                             │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"G"}│{"Name":"A"}│[{"Name":"G"},{"dist":"1"},{"Name":"D"},{"Name":"D"},{"dist":"3"},{"Na│18        │
│            │            │me":"C"},{"Name":"C"},{"dist":"2"},{"Name":"J"},{"Name":"J"},{"dist":"│          │
│            │            │7"},{"Name":"F"},{"Name":"F"},{"dist":"5"},{"Name":"A"}]              │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"G"}│{"Name":"F"}│[{"Name":"G"},{"dist":"1"},{"Name":"D"},{"Name":"D"},{"dist":"3"},{"Na│13        │
│            │            │me":"C"},{"Name":"C"},{"dist":"2"},{"Name":"J"},{"Name":"J"},{"dist":"│          │
│            │            │7"},{"Name":"F"}]                                                     │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"G"}│{"Name":"B"}│[{"Name":"G"},{"dist":"1"},{"Name":"D"},{"Name":"D"},{"dist":"3"},{"Na│11        │
│            │            │me":"C"},{"Name":"C"},{"dist":"7"},{"Name":"B"}]                      │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"G"}│{"Name":"J"}│[{"Name":"G"},{"dist":"1"},{"Name":"D"},{"Name":"D"},{"dist":"3"},{"Na│6         │
│            │            │me":"C"},{"Name":"C"},{"dist":"2"},{"Name":"J"}]                      │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"G"}│{"Name":"E"}│[{"Name":"G"},{"dist":"1"},{"Name":"D"},{"Name":"D"},{"dist":"4"},{"Na│5         │
│            │            │me":"E"}]                                                             │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"G"}│{"Name":"C"}│[{"Name":"G"},{"dist":"1"},{"Name":"D"},{"Name":"D"},{"dist":"3"},{"Na│4         │
│            │            │me":"C"}]                                                             │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"G"}│{"Name":"P"}│[{"Name":"G"},{"dist":"4"},{"Name":"P"}]                              │4         │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"G"}│{"Name":"D"}│[{"Name":"G"},{"dist":"1"},{"Name":"D"}]                              │1         │
└────────────┴────────────┴──────────────────────────────────────────────────────────────────────┴──────────┘

MATCH (from: MyNode {Name:'H'}), (to: MyNode),
path = shortestPath((from)-[:TO*]->(to))
where to.Name <> 'H'
WITH REDUCE(dist = 0, rel in rels(path) | dist + toInt(rel.dist)) AS distance, path, from, to limit 10
RETURN from, to, path, distance order by distance desc

╒════════════╤════════════╤══════════════════════════════════════════════════════════════════════╤══════════╕
│"from"      │"to"        │"path"                                                                │"distance"│
╞════════════╪════════════╪══════════════════════════════════════════════════════════════════════╪══════════╡
│{"Name":"H"}│{"Name":"P"}│[{"Name":"H"},{"dist":"5"},{"Name":"J"},{"Name":"J"},{"dist":"7"},{"Na│39        │
│            │            │me":"F"},{"Name":"F"},{"dist":"5"},{"Name":"A"},{"Name":"A"},{"dist":"│          │
│            │            │6"},{"Name":"L"},{"Name":"L"},{"dist":"8"},{"Name":"E"},{"Name":"E"},{│          │
│            │            │"dist":"4"},{"Name":"G"},{"Name":"G"},{"dist":"4"},{"Name":"P"}]      │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"H"}│{"Name":"G"}│[{"Name":"H"},{"dist":"5"},{"Name":"J"},{"Name":"J"},{"dist":"7"},{"Na│35        │
│            │            │me":"F"},{"Name":"F"},{"dist":"5"},{"Name":"A"},{"Name":"A"},{"dist":"│          │
│            │            │6"},{"Name":"L"},{"Name":"L"},{"dist":"8"},{"Name":"E"},{"Name":"E"},{│          │
│            │            │"dist":"4"},{"Name":"G"}]                                             │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"H"}│{"Name":"D"}│[{"Name":"H"},{"dist":"5"},{"Name":"J"},{"Name":"J"},{"dist":"7"},{"Na│32        │
│            │            │me":"F"},{"Name":"F"},{"dist":"5"},{"Name":"A"},{"Name":"A"},{"dist":"│          │
│            │            │3"},{"Name":"C"},{"Name":"C"},{"dist":"7"},{"Name":"B"},{"Name":"B"},{│          │
│            │            │"dist":"5"},{"Name":"D"}]                                             │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"H"}│{"Name":"E"}│[{"Name":"H"},{"dist":"5"},{"Name":"J"},{"Name":"J"},{"dist":"7"},{"Na│31        │
│            │            │me":"F"},{"Name":"F"},{"dist":"5"},{"Name":"A"},{"Name":"A"},{"dist":"│          │
│            │            │6"},{"Name":"L"},{"Name":"L"},{"dist":"8"},{"Name":"E"}]              │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"H"}│{"Name":"B"}│[{"Name":"H"},{"dist":"5"},{"Name":"J"},{"Name":"J"},{"dist":"7"},{"Na│27        │
│            │            │me":"F"},{"Name":"F"},{"dist":"5"},{"Name":"A"},{"Name":"A"},{"dist":"│          │
│            │            │3"},{"Name":"C"},{"Name":"C"},{"dist":"7"},{"Name":"B"}]              │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"H"}│{"Name":"L"}│[{"Name":"H"},{"dist":"5"},{"Name":"J"},{"Name":"J"},{"dist":"7"},{"Na│23        │
│            │            │me":"F"},{"Name":"F"},{"dist":"5"},{"Name":"A"},{"Name":"A"},{"dist":"│          │
│            │            │6"},{"Name":"L"}]                                                     │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"H"}│{"Name":"C"}│[{"Name":"H"},{"dist":"5"},{"Name":"J"},{"Name":"J"},{"dist":"7"},{"Na│20        │
│            │            │me":"F"},{"Name":"F"},{"dist":"5"},{"Name":"A"},{"Name":"A"},{"dist":"│          │
│            │            │3"},{"Name":"C"}]                                                     │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"H"}│{"Name":"A"}│[{"Name":"H"},{"dist":"5"},{"Name":"J"},{"Name":"J"},{"dist":"7"},{"Na│17        │
│            │            │me":"F"},{"Name":"F"},{"dist":"5"},{"Name":"A"}]                      │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"H"}│{"Name":"F"}│[{"Name":"H"},{"dist":"5"},{"Name":"J"},{"Name":"J"},{"dist":"7"},{"Na│12        │
│            │            │me":"F"}]                                                             │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"H"}│{"Name":"J"}│[{"Name":"H"},{"dist":"5"},{"Name":"J"}]                              │5         │
└────────────┴────────────┴──────────────────────────────────────────────────────────────────────┴──────────┘

MATCH (from: MyNode {Name:'J'}), (to: MyNode),
path = shortestPath((from)-[:TO*]->(to))
where to.Name <> 'J'
WITH REDUCE(dist = 0, rel in rels(path) | dist + toInt(rel.dist)) AS distance, path, from, to limit 10
RETURN from, to, path, distance order by distance desc

╒════════════╤════════════╤══════════════════════════════════════════════════════════════════════╤══════════╕
│"from"      │"to"        │"path"                                                                │"distance"│
╞════════════╪════════════╪══════════════════════════════════════════════════════════════════════╪══════════╡
│{"Name":"J"}│{"Name":"P"}│[{"Name":"J"},{"dist":"7"},{"Name":"F"},{"Name":"F"},{"dist":"5"},{"Na│34        │
│            │            │me":"A"},{"Name":"A"},{"dist":"6"},{"Name":"L"},{"Name":"L"},{"dist":"│          │
│            │            │8"},{"Name":"E"},{"Name":"E"},{"dist":"4"},{"Name":"G"},{"Name":"G"},{│          │
│            │            │"dist":"4"},{"Name":"P"}]                                             │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"J"}│{"Name":"G"}│[{"Name":"J"},{"dist":"7"},{"Name":"F"},{"Name":"F"},{"dist":"5"},{"Na│30        │
│            │            │me":"A"},{"Name":"A"},{"dist":"6"},{"Name":"L"},{"Name":"L"},{"dist":"│          │
│            │            │8"},{"Name":"E"},{"Name":"E"},{"dist":"4"},{"Name":"G"}]              │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"J"}│{"Name":"D"}│[{"Name":"J"},{"dist":"7"},{"Name":"F"},{"Name":"F"},{"dist":"5"},{"Na│27        │
│            │            │me":"A"},{"Name":"A"},{"dist":"3"},{"Name":"C"},{"Name":"C"},{"dist":"│          │
│            │            │7"},{"Name":"B"},{"Name":"B"},{"dist":"5"},{"Name":"D"}]              │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"J"}│{"Name":"E"}│[{"Name":"J"},{"dist":"7"},{"Name":"F"},{"Name":"F"},{"dist":"5"},{"Na│26        │
│            │            │me":"A"},{"Name":"A"},{"dist":"6"},{"Name":"L"},{"Name":"L"},{"dist":"│          │
│            │            │8"},{"Name":"E"}]                                                     │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"J"}│{"Name":"B"}│[{"Name":"J"},{"dist":"7"},{"Name":"F"},{"Name":"F"},{"dist":"5"},{"Na│22        │
│            │            │me":"A"},{"Name":"A"},{"dist":"3"},{"Name":"C"},{"Name":"C"},{"dist":"│          │
│            │            │7"},{"Name":"B"}]                                                     │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"J"}│{"Name":"L"}│[{"Name":"J"},{"dist":"7"},{"Name":"F"},{"Name":"F"},{"dist":"5"},{"Na│18        │
│            │            │me":"A"},{"Name":"A"},{"dist":"6"},{"Name":"L"}]                      │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"J"}│{"Name":"C"}│[{"Name":"J"},{"dist":"7"},{"Name":"F"},{"Name":"F"},{"dist":"5"},{"Na│15        │
│            │            │me":"A"},{"Name":"A"},{"dist":"3"},{"Name":"C"}]                      │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"J"}│{"Name":"A"}│[{"Name":"J"},{"dist":"7"},{"Name":"F"},{"Name":"F"},{"dist":"5"},{"Na│12        │
│            │            │me":"A"}]                                                             │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"J"}│{"Name":"F"}│[{"Name":"J"},{"dist":"7"},{"Name":"F"}]                              │7         │
└────────────┴────────────┴──────────────────────────────────────────────────────────────────────┴──────────┘

MATCH (from: MyNode {Name:'L'}), (to: MyNode),
path = shortestPath((from)-[:TO*]->(to))
where to.Name <> 'L'
WITH REDUCE(dist = 0, rel in rels(path) | dist + toInt(rel.dist)) AS distance, path, from, to limit 10
RETURN from, to, path, distance order by distance desc

╒════════════╤════════════╤══════════════════════════════════════════════════════════════════════╤══════════╕
│"from"      │"to"        │"path"                                                                │"distance"│
╞════════════╪════════════╪══════════════════════════════════════════════════════════════════════╪══════════╡
│{"Name":"L"}│{"Name":"A"}│[{"Name":"L"},{"dist":"8"},{"Name":"E"},{"Name":"E"},{"dist":"4"},{"Na│30        │
│            │            │me":"G"},{"Name":"G"},{"dist":"1"},{"Name":"D"},{"Name":"D"},{"dist":"│          │
│            │            │3"},{"Name":"C"},{"Name":"C"},{"dist":"2"},{"Name":"J"},{"Name":"J"},{│          │
│            │            │"dist":"7"},{"Name":"F"},{"Name":"F"},{"dist":"5"},{"Name":"A"}]      │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"L"}│{"Name":"F"}│[{"Name":"L"},{"dist":"8"},{"Name":"E"},{"Name":"E"},{"dist":"4"},{"Na│25        │
│            │            │me":"G"},{"Name":"G"},{"dist":"1"},{"Name":"D"},{"Name":"D"},{"dist":"│          │
│            │            │3"},{"Name":"C"},{"Name":"C"},{"dist":"2"},{"Name":"J"},{"Name":"J"},{│          │
│            │            │"dist":"7"},{"Name":"F"}]                                             │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"L"}│{"Name":"B"}│[{"Name":"L"},{"dist":"8"},{"Name":"E"},{"Name":"E"},{"dist":"4"},{"Na│23        │
│            │            │me":"G"},{"Name":"G"},{"dist":"1"},{"Name":"D"},{"Name":"D"},{"dist":"│          │
│            │            │3"},{"Name":"C"},{"Name":"C"},{"dist":"7"},{"Name":"B"}]              │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"L"}│{"Name":"J"}│[{"Name":"L"},{"dist":"8"},{"Name":"E"},{"Name":"E"},{"dist":"4"},{"Na│18        │
│            │            │me":"G"},{"Name":"G"},{"dist":"1"},{"Name":"D"},{"Name":"D"},{"dist":"│          │
│            │            │3"},{"Name":"C"},{"Name":"C"},{"dist":"2"},{"Name":"J"}]              │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"L"}│{"Name":"C"}│[{"Name":"L"},{"dist":"8"},{"Name":"E"},{"Name":"E"},{"dist":"4"},{"Na│16        │
│            │            │me":"G"},{"Name":"G"},{"dist":"1"},{"Name":"D"},{"Name":"D"},{"dist":"│          │
│            │            │3"},{"Name":"C"}]                                                     │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"L"}│{"Name":"P"}│[{"Name":"L"},{"dist":"8"},{"Name":"E"},{"Name":"E"},{"dist":"4"},{"Na│16        │
│            │            │me":"G"},{"Name":"G"},{"dist":"4"},{"Name":"P"}]                      │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"L"}│{"Name":"D"}│[{"Name":"L"},{"dist":"8"},{"Name":"E"},{"Name":"E"},{"dist":"4"},{"Na│13        │
│            │            │me":"G"},{"Name":"G"},{"dist":"1"},{"Name":"D"}]                      │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"L"}│{"Name":"G"}│[{"Name":"L"},{"dist":"8"},{"Name":"E"},{"Name":"E"},{"dist":"4"},{"Na│12        │
│            │            │me":"G"}]                                                             │          │
├────────────┼────────────┼──────────────────────────────────────────────────────────────────────┼──────────┤
│{"Name":"L"}│{"Name":"E"}│[{"Name":"L"},{"dist":"8"},{"Name":"E"}]                              │8         │
└────────────┴────────────┴──────────────────────────────────────────────────────────────────────┴──────────┘

If you have comments or questions regarding this or any other post in this blog, please leave me a comment and I will reply as soon as possible.

Regards;

John

Follow me on Twitter:  @john_canessa

One thought on “Neo4j and Dijkstra’s SSSP”

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.