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 |
==> +-----------------------------------------------------------------+