Counting the relationships of all neighbours' neighbours

时间:2016-07-11 22:54:39

标签: neo4j

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

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

Then I have the following graph:

  • User 1 likes 4 users: 2, 3, 4, 5.
  • User 2 likes users 4, 1, 3, 5.
  • User 3 likes users 4, 1, 5.
  • User 4 likes users 1, 2, 3.
  • User 5 likes users 4, 2, 1.

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:

  • User 2: 3 edges (4, 3, 5).
  • User 3: 2 edges (4, 5).
  • User 4: 2 edges (2, 3).
  • User 5: 2 edges (4, 2).

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

1 个答案:

答案 0 :(得分:2)

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