The difference is obvious while dealing with big dataset. Below is an example SQL query for retrieving all connections among users in selected distance:
with recursive cluster (party, path, depth) as (
select cast(@userId as character varying), cast(@userId as character varying), 1 union ( select (case when this.party = amc.userA then amc.userB when this.party = amc.userB then amc.userA end), (this.path || '.' || (case when this.party = amc.userA then amc.userB when this.party = amc.userB then amc.userA end)), this.depth + 1 from cluster this, chat amc where ((this.party = amc.userA and position(amc.userB in this.path) = 0) or (this.party = amc.userB and position(amc.userA in this.path) = 0)) AND this.depth < @depth + 1
)
) select party, path from cluster where not exists ( select * from cluster c2
where cluster.party = c2.party and ( char_length(cluster.path) > char_length(c2.path) or (char_length(cluster.path) = char_length(c2.path)) and (cluster.path > c2.path) ) ) order by party, path;
Running such query on database with several million users and connections takes very long time (talking in hours on proprietary PC).
Below is the Cypher query for neo4j database which counts all friends of friends (equivalent to above one in case of depth = 2)
neo4j-sh (0)$ start b = node:User(UserId='9F56478E6CAFB9CFF8C720C5DFC392C49495C582') MATCH (b) --(friend)--(friendoffriend) RETURN count(friendoffriend)==> +-----------------------+==> | count(friendoffriend) |==> +-----------------------+==> | 131457 |==> +-----------------------+==> 1 row, 635 msThe advantage in performance and simplicity is obvious.
Running queries in neo4j console
Below are some more example Cypher queries for working with graphs. you can try out these and other on simple example network on this website.
![]() |
| Graph Screenshot from neo4j Console |
Find Neighbors
start a=node(*)
match (a)-->(b)
return a, b;
+-----------------------+
| a | b |
+-----------------------+
| Node[0]{} | Node[1]{} |
| Node[1]{} | Node[2]{} |
| Node[1]{} | Node[3]{} |
| Node[1]{} | Node[4]{} |
| Node[1]{} | Node[5]{} |
| Node[2]{} | Node[6]{} |
| Node[2]{} | Node[7]{} |
| Node[3]{} | Node[4]{} |
| Node[5]{} | Node[6]{} |
+-----------------------+
9 rows
0 ms
Find Mutual Connections
start a=node(*), b=node(*)
match (a)--(x)--(b)
return a, b, x
+-----------------------------------+
| a | b | x |
+-----------------------------------+
| Node[0]{} | Node[2]{} | Node[1]{} |
| Node[0]{} | Node[3]{} | Node[1]{} |
| Node[0]{} | Node[4]{} | Node[1]{} |
| Node[0]{} | Node[5]{} | Node[1]{} |
| Node[1]{} | Node[3]{} | Node[4]{} |
| Node[1]{} | Node[4]{} | Node[3]{} |
| Node[1]{} | Node[6]{} | Node[2]{} |
| Node[1]{} | Node[6]{} | Node[5]{} |
| Node[1]{} | Node[7]{} | Node[2]{} |
| Node[2]{} | Node[0]{} | Node[1]{} |
| Node[2]{} | Node[3]{} | Node[1]{} |
| Node[2]{} | Node[4]{} | Node[1]{} |
| Node[2]{} | Node[5]{} | Node[6]{} |
| Node[2]{} | Node[5]{} | Node[1]{} |
| Node[3]{} | Node[0]{} | Node[1]{} |
| Node[3]{} | Node[1]{} | Node[4]{} |
| Node[3]{} | Node[2]{} | Node[1]{} |
| Node[3]{} | Node[4]{} | Node[1]{} |
| Node[3]{} | Node[5]{} | Node[1]{} |
| Node[4]{} | Node[0]{} | Node[1]{} |
| Node[4]{} | Node[1]{} | Node[3]{} |
| Node[4]{} | Node[2]{} | Node[1]{} |
| Node[4]{} | Node[3]{} | Node[1]{} |
| Node[4]{} | Node[5]{} | Node[1]{} |
| Node[5]{} | Node[0]{} | Node[1]{} |
| Node[5]{} | Node[2]{} | Node[6]{} |
| Node[5]{} | Node[2]{} | Node[1]{} |
| Node[5]{} | Node[3]{} | Node[1]{} |
| Node[5]{} | Node[4]{} | Node[1]{} |
| Node[6]{} | Node[1]{} | Node[2]{} |
| Node[6]{} | Node[1]{} | Node[5]{} |
| Node[6]{} | Node[7]{} | Node[2]{} |
| Node[7]{} | Node[1]{} | Node[2]{} |
| Node[7]{} | Node[6]{} | Node[2]{} |
+-----------------------------------+
34 rows
0 ms
Count Mutual Connections
start a=node(*), b=node(*)
match (a)--(x)--(b)
where id(a) < id(b)
return a, b, count(distinct x)
+-------------------------------------------+
| a | b | count(distinct x) |
+-------------------------------------------+
| Node[0]{} | Node[5]{} | 1 |
| Node[2]{} | Node[5]{} | 2 |
| Node[3]{} | Node[4]{} | 1 |
| Node[6]{} | Node[7]{} | 1 |
| Node[1]{} | Node[4]{} | 1 |
| Node[0]{} | Node[3]{} | 1 |
| Node[4]{} | Node[5]{} | 1 |
| Node[1]{} | Node[6]{} | 2 |
| Node[0]{} | Node[4]{} | 1 |
| Node[1]{} | Node[7]{} | 1 |
| Node[0]{} | Node[2]{} | 1 |
| Node[1]{} | Node[3]{} | 1 |
| Node[2]{} | Node[3]{} | 1 |
| Node[2]{} | Node[4]{} | 1 |
| Node[3]{} | Node[5]{} | 1 |
+-------------------------------------------+
15 rows
0 ms
Calculate Clustering Coefficient
start a = node(1)
match (a)--(b)
with a, b as neighbours
match (a)--()-[r]-()--(a)
where id(a) <> id(neighbours) and id(neighbours) <> 0
return count(distinct neighbours), count(distinct r)
+------------------------------------------------+
| count(distinct neighbours) | count(distinct r) |
+------------------------------------------------+
| 4 | 1 |
+------------------------------------------------+
1 row
0 ms
The clustering coefficient of a selected node is defined as probability that two randomly selected neighbors are connected to each other. So once having number of neighbors and number of mutual connections we can calculate:
1. The number of possible connections between two neighbors = n!/(2!(n-2)!) = 4!/(2!(4-2)!) = 24/4 = 6
where n is the number of neighbors n = 4
and the actual number of connections is 1,
therefore the clustering coefficient of node 1 is 1/6
References
Cypher Query Language
Networks, Crowds, and Markets: Reasoning About a Highly Connected World By David Easley and Jon Kleinberg

















