Skip to content

Instantly share code, notes, and snippets.

@freeeve
Forked from aseemk/neo4j-cypher-weighted-followers.md
Last active December 31, 2015 21:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save freeeve/8049783 to your computer and use it in GitHub Desktop.
Save freeeve/8049783 to your computer and use it in GitHub Desktop.

Upgraded for 2.0:

MATCH (user:User)<-[:follows]-(follower)
OPTIONAL MATCH (follower)-[:follows]->(other)
WITH user, follower, 1.0 / (0.0 + COUNT(other)) AS weighted
WITH user, COUNT(follower) AS numFollowers, SUM(weighted) AS totalWeighted
RETURN user, numFollowers, ROUND(totalWeighted * 100) / 100.0 AS totalWeighted
ORDER BY ID(user)

The idea is to weigh followers more who follow fewer other people. So for each follower, their "weighted" contribution is 1 / numFollowing. To prevent division by zero, the user is included in the "following".

The result is that this "normalized" follower count is always less than your "simple" follower count -- but roughly in the same ballpark! Nice.

One missing feature of the current query is that it ignores users w/ no followers. We can include them by changing the first relationship to an optional match, too, but then we get back to divison by zero. We could always add 1 to numFollowing, but then that gives users with no followers a weighted follower count of 1, and users with actual followers a potentially lower weighted follower count. Haven't figured out how to solve this yet.

Run against the current http://node-neo4j-template.herokuapp.com/ database:

==> +-----------------------------------------------------------------+
==> | user                             | numFollowers | totalWeighted |
==> +-----------------------------------------------------------------+
==> | Node[3]{name:"ii"}               | 4            | 1.67          |
==> | Node[8]{name:"百度"}              | 6            | 2.62          |
==> | Node[13]{name:"testme"}          | 2            | 0.83          |
==> | Node[15]{name:"Jgl"}             | 12           | 5.73          |
==> | Node[16]{name:"xad2"}            | 16           | 6.23          |
==> | Node[17]{name:"akbar"}           | 6            | 3.67          |
==> | Node[19]{name:"lalita"}          | 1            | 0.33          |
==> | Node[20]{name:"nice-app-thanks"} | 1            | 0.25          |
==> | Node[21]{name:"wowsy"}           | 8            | 4.31          |
==> | Node[23]{name:"jhgfjhgf"}        | 10           | 5.87          |
==> | Node[24]{name:"suroor"}          | 1            | 0.33          |
==> | Node[28]{name:"john2"}           | 1            | 1.0           |
==> | Node[31]{name:"pruebajuandd18"}  | 2            | 0.67          |
==> | Node[32]{name:"manish"}          | 2            | 0.83          |
==> | Node[33]{name:"dibz"}            | 2            | 0.5           |
==> | Node[34]{name:"demian"}          | 1            | 0.5           |
==> | Node[35]{name:"kumar"}           | 6            | 2.84          |
==> | Node[36]{name:"oliverjash"}      | 1            | 0.25          |
==> | Node[38]{name:"Mom"}             | 1            | 0.33          |
==> | Node[43]{name:" pete"}           | 1            | 0.5           |
==> | Node[45]{name:"sarah"}           | 2            | 0.39          |
==> | Node[46]{name:"diman1"}          | 1            | 0.33          |
==> | Node[48]{name:"tilli"}           | 9            | 3.78          |
==> | Node[52]{name:"HLASJQ"}          | 2            | 1.5           |
==> | Node[53]{name:"Momo"}            | 8            | 4.0           |
==> | Node[54]{name:"pepperone233"}    | 2            | 0.45          |
==> | Node[57]{name:"ElSebita"}        | 7            | 3.68          |
==> | Node[58]{name:"rahul"}           | 5            | 1.28          |
==> | Node[59]{name:"blup"}            | 1            | 1.0           |
==> | Node[60]{name:"demian2"}         | 13           | 7.14          |
==> | Node[62]{name:"Purnendu"}        | 3            | 1.08          |
==> | Node[63]{name:"test"}            | 8            | 4.33          |
==> | Node[67]{name:"woowee"}          | 4            | 2.39          |
==> | Node[68]{name:"jimz"}            | 1            | 1.0           |
==> | Node[73]{name:"ryan"}            | 1            | 0.25          |
==> | Node[75]{name:"träte2"}          | 2            | 0.58          |
==> | Node[76]{name:"ohMy"}            | 1            | 0.5           |
==> | Node[82]{name:"alex"}            | 1            | 0.25          |
==> | Node[85]{name:"fremNOKdegroBO"}  | 4            | 1.08          |
==> | Node[90]{name:"teest"}           | 6            | 2.03          |
==> | Node[93]{name:"tasinet"}         | 1            | 0.5           |
==> | Node[94]{name:"Щы"}              | 1            | 0.17          |
==> +-----------------------------------------------------------------+
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment