Luciano
Luciano

Reputation: 43

Counting the relationships of all neighbours' neighbours

Suppose I have node called User that has a relationship "Likes" towards another User.

(u1)-[:Likes]->(u2)

Then I have the following graph:

For User 1, I want to find out his neighbours and the total number of edges that his neighbours have, not counting the edges coming back to User 1. So it'd be:

So the query should return 4 (number of neighbours) and 9 (number of edges of his neighbours).

I'm not sure how to do this counter for each one the neighbours, I tried by adding a property on User 1 and using it as acummulator, but didn't work very well. (I'd rather do it without creating a new attribute on User 1).

MATCH (u1)-[r:Likes]->(u2)
WHERE u1.id = 1
SET u1.n_edges = 0
WITH u1, COLLECT(DISTINCT(u2.id)) as neighbours, COUNT(DISTINCT(u2)) as k
UNWIND neighbours as n
MATCH (u3:User{id:n})-[r:Likes]->(u4)
WHERE u4 <> u1
WITH u1, neighbours, k, COUNT(DISTINCT(u4)) as cnt
SET u1.n_edges = u1.n_edges + cnt
RETURN k, u1.n_edges

Upvotes: 1

Views: 434

Answers (1)

William Lyon
William Lyon

Reputation: 8546

This should return 1 row for each neighbor of u1 with their neighbor count, excluding u1:

MATCH (u1:User) WHERE u1.name = "User 1"
MATCH (u1)-[:LIKES]->(n:User)
MATCH (n)-[:LIKES]->(o) WHERE id(o) <> id(u1)
RETURN n.name, count(*) AS neighbors_excluding_u1

Then if all you want are the counts:

MATCH (u1:User) WHERE u1.name = "User 1"
WITH (u1)-[:LIKES]->(n:User)
WITH count(*) AS n_neighbors, u1
MATCH (u1)-[:LIKES]->(o:User)-[:LIKES]-(fof:User)
RETURN n_neighbors, count(*) AS fof_rel_count

Upvotes: 2

Related Questions