Skip to content

Commit

Permalink
Add followers count cache for future queries
Browse files Browse the repository at this point in the history
  • Loading branch information
dcadenas committed Sep 8, 2024
1 parent 661ed29 commit d8d6779
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 18 deletions.
16 changes: 0 additions & 16 deletions backfills/README.md

This file was deleted.

1 change: 1 addition & 0 deletions migrations/002_followers_count_index.cypher
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CREATE INDEX FOR (u:User) ON (u.follower_count);
3 changes: 3 additions & 0 deletions queries/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Queries Directory

This directory contains Neo4j Cypher queries intended for manual database changes, data inspection, and analysis. These queries can be used to make one-off updates, verify data integrity, and generate insights for reporting. As the project evolves, this collection will grow and be used for ongoing database analysis and reporting.
16 changes: 16 additions & 0 deletions queries/find_spammers.cypher
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Looks for users with more than 100 followers that have too many followers with very few followees

MATCH (suspect:User)-[f:FOLLOWS]->(target:User)
WITH target, COUNT(DISTINCT suspect) AS num_followers
WHERE num_followers > 100
WITH target, num_followers
ORDER BY num_followers DESC
LIMIT 10
MATCH (suspect:User)-[f:FOLLOWS]->(target:User)
MATCH (suspect)-[:FOLLOWS]->(others:User)
WITH target, num_followers, suspect, COUNT(DISTINCT others) AS num_followees
WHERE num_followees < 3
WITH target, num_followers, COUNT(DISTINCT suspect) AS num_suspects
ORDER BY num_suspects DESC
RETURN target, num_followers, num_suspects
LIMIT 10;
12 changes: 12 additions & 0 deletions queries/set_null_followers_counts_values.cypher
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// This query selects up to 1000 users with a null follower count, counts their
// followers, updates the follower count, and returns the user’s public key
// along with the updated count.

MATCH (user:User)
WHERE user.follower_count IS NULL
WITH user
LIMIT 1000
OPTIONAL MATCH (follower:User)-[:FOLLOWS]->(user)
WITH user, COUNT(follower) AS follower_count
SET user.follower_count = follower_count
RETURN user.pubkey, user.follower_count;
22 changes: 20 additions & 2 deletions src/repo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,12 +166,25 @@ impl RepoTrait for Repo {
}

async fn upsert_follow(&self, follow: &ContactListFollow) -> Result<(), RepoError> {
// Notice we only increment follower_count if it is not null. This
// allows an external script to initialize the count with fresh,
// non-cached values.
let statement = r#"
MERGE (followee:User {pubkey: $followee_val})
ON CREATE SET followee.follower_count = 0
MERGE (follower:User {pubkey: $follower_val})
MERGE (follower)-[r:FOLLOWS]->(followee)
ON CREATE SET r.created_at = $updated_at, r.updated_at = $updated_at
ON MATCH SET r.updated_at = $updated_at
ON CREATE SET
r.created_at = $updated_at,
r.updated_at = $updated_at,
followee.follower_count = CASE
WHEN followee.follower_count IS NOT NULL THEN followee.follower_count + 1
ELSE followee.follower_count
END
ON MATCH SET
r.updated_at = $updated_at
"#;

let query = query(statement)
Expand All @@ -195,6 +208,11 @@ impl RepoTrait for Repo {
let statement = r#"
MATCH (follower:User {pubkey: $follower_val})-[r:FOLLOWS]->(followee:User {pubkey: $followee_val})
DELETE r
WITH followee
SET followee.follower_count = CASE
WHEN followee.follower_count > 0 THEN followee.follower_count - 1
ELSE 0
END
"#;

let query = query(statement)
Expand Down

0 comments on commit d8d6779

Please sign in to comment.