SlideShare a Scribd company logo
Analysing Github events with Neo4j
#whoami 
‱ Christophe Willemsen 
‱ Bruges (Belgium) 
‱ Created Graphgen (graphgen.neoxygen.io) 
! 
! 
! 
! 
‱ @ Graph Aware
#how-it-started
#github-data-archive 
‱ Github Events 
‱ archive available @ http://www.githubarchive.org/ 
‱ events json files per hour 
‱ approx. 10k events per hour 
‱ ! the file in itself is not valid json, all file rows are 
valid json
#event-types 
‱ CommitCommentEvent 
‱ CreateEvent 
‱ DeleteEvent 
‱ DeploymentEvent 
‱ DeploymentStatusEvent 
‱ DownloadEvent 
‱ FollowEvent 
‱ ForkEvent 
‱ ForkApplyEvent 
‱ GistEvent 
‱ GollumEvent 
‱ IssueCommentEvent 
‱ IssuesEvent 
‱ MemberEvent 
‱ PageBuildEvent 
‱ PublicEvent 
‱ PullRequestEvent 
‱ PullRequestReviewCommentEvent 
‱ PushEvent 
‱ ReleaseEvent 
‱ StatusEvent 
‱ TeamAddEvent 
‱ WatchEvent
#gh4j 
Github Events importer for Neo4j 
Parse file + build customized Cypher Statements for 
each event + load in Neo4j
#PullRequestEvent 
Payload and informations from the past 
‱ You get information of the PR 
‱ You can also build informations about the repo, who is 
owning it for e.g. 
‱ On which branch 
‱ Depending of the P.R. Action (open/close/merge), you 
can determine for a close/merge who opened first the PR 
and from which fork it is coming
MERGE (u:User {name:'pixelfreak2005'}) 
CREATE (ev:PullRequestEvent {time:toInt(1401606356) }) 
MERGE (u)-[:DO]->(ev) 
MERGE (pr:PullRequest {html_url:'https://github.com/pixelfreak2005/liqiud_android_packages_apps_Settings/pull/2'}) 
SET pr += { id:toInt(16573622), number:toInt(2), state:'open'} 
MERGE (ev)-[:PR_OPEN]->(pr) 
MERGE (ow:User {name:'pixelfreak2005'}) 
MERGE (or:Repository {id:toInt(20338536), name:'liqiud_android_packages_apps_Settings'}) 
MERGE (or)-[:OWNED_BY]->(ow) 
MERGE (pr)-[:PR_ON_REPO]->(or)
#ForkEvent 
MERGE (u:User {name:'rudymalhi'}) 
CREATE (ev:ForkEvent {time:toInt(1401606379) }) MERGE (u)-[:DO]->(ev) 
CREATE (fork:Fork:Repository {name:'Full-Stack-JS-Nodember'}) 
MERGE (ev)-[:FORK]->(fork)-[:OWNED_BY]->(u) 
MERGE (bro:User {name:'mgenev'}) 
MERGE (br:Repository {id:toInt(15503488), name:'Full-Stack-JS-Nodember'})-[:OWNED_BY]->(bro) 
MERGE (fork)-[:FORK_OF]->(br)
#IssueCommentEvent 
You can check if the issue is related to a P.R. and build the complete P.R. schema 
MERGE (u:User {name:'johanneswilm'}) 
CREATE (ev:IssueCommentEvent {time:toInt(1401606384) }) 
MERGE (u)-[:DO]->(ev) 
MERGE (comment:IssueComment {id:toInt(44769338)}) 
MERGE (ev)-[:ISSUE_COMMENT]->(comment) 
MERGE (issue:Issue {id:toInt(34722578)}) 
MERGE (repo:Repository {id:toInt(14487686)}) 
MERGE (comment)-[:COMMENT_ON]->(issue)-[:ISSUE_ON]->(repo) 
SET repo.name = 'diffDOM' 
MERGE (owner:User {name:'fiduswriter'}) 
MERGE (comment)-[:COMMENT_ON]->(issue)-[:ISSUE_ON]->(repo)-[:OWNED_BY]->(owner)
Let’s have some fun and try some queries 
! 
demo
who did the most events ? 
! 
MATCH (u:User)-[r:DO]->() 
RETURN u.name, count(r) as events 
ORDER BY events DESC 
LIMIT 1
which repo has been the most touched ? 
! 
MATCH (repo:Repository)<-[r]-() 
RETURN repo.name, count(r) as touchs 
ORDER BY touchs DESC 
LIMIT 1
which repo has been the most forked ? 
! 
MATCH (repo:Repository)<-[:FORK_OF]-(fork:Fork)<-[:FORK]- 
(event:ForkEvent) 
RETURN repo.name, count(event) as forks 
ORDER BY forks DESC 
LIMIT 1
which repo has the most merged PRs ? 
! 
MATCH (repo:Repository)<-[:PR_ON_REPO]- 
(pr:PullRequest)<-[merge:PR_MERGE]-() 
RETURN repo.name, count(merge) as merges 
ORDER BY merges DESC 
LIMIT 1
how much forks are resulting in an open PR ? 
! 
MATCH p=(u:User)-[:DO]->(fe:ForkEvent)-[:FORK]->(fork:Fork) 
-[:FORK_OF]->(repo:Repository)<-[:PR_ON_REPO]-(pr:PullRequest) 
-[:PR_OPEN]-(pre:PullRequestEvent)<-[:DO]-(u2:User)<-[:OWNED_BY]- 
(f2:Fork)<-[:BRANCH_OF]-(br:Branch)<-[:FROM_BRANCH]-(pr2:PullRequest) 
WHERE u = u2 AND fork = f2 AND pr = pr2 
RETURN count(p)
Analysing Github events with Neo4j
Number of comments on a PR before the PR is merged ? 
! 
MATCH p=(ice:IssueCommentEvent)-[:ISSUE_COMMENT]->(comment:IssueComment) 
-[:COMMENT_ON]->(issue:Issue)-[:BOUND_TO_PR]->(pr:PullRequest) 
<-[:PR_MERGE]-(pre:PullRequestEvent) 
WHERE ice.time <= pre.time 
WITH pr, count(comment) as comments 
RETURN avg(comments)
Top contributor ? 
Which user has the most merged PR’s on repositories 
not owned by him 
! 
MATCH (u:User)-[r:DO]->(fe:PullRequestEvent)-[:PR_OPEN]->(pr:PullRequest {state:'merged'}) 
-[:PR_ON_REPO]-(repo:Repository)-[:OWNED_BY]->(u2:User) 
WHERE NOT u = u2 
RETURN u.name, count(r) as prs 
ORDER BY prs DESC 
LIMIT 1
Relate together Users having Merged PR's on same 
repositories, could serve as Follow Recommendations Engine! 
! 
MATCH p=(u:User)-[:DO]-(e:PullRequestEvent)-->(pr:PullRequest {state:'merged'})- 
[:PR_ON_REPO]->(r:Repository)<-[:PR_ON_REPO]-(pr2:PullRequest 
{state:'merged'})--(e2:PullRequestEvent)<-[:DO]-(u2:User) 
WHERE NOT u = u2 
WITH nodes(p) as coll 
WITH head(coll) as st, last(coll) as end 
MERGE (st)-[r:HAVE_WORKED_ON_SAME_REPO]-(end) 
ON MATCH SET r.w = (r.w) + 1 
ON CREATE SET r.w = 1
QUESTIONS ?
‱ More queries in the gist file : https://gist.github.com/ikwattro/ 
071d36f135131e8e4442 
‱ Not valid with Github Live API (different payload) 
‱ zipped db file http://bit.ly/1BaMCy9
THANK YOU 
@ikwattro
avg time between a repo is forked and this fork result in 
an opened PR ? 
! 
MATCH p=(u:User)-[:DO]->(fe:ForkEvent)-[:FORK]->(fork:Fork)-[:FORK_OF] 
->(repo:Repository)<-[:PR_ON_REPO]-(pr:PullRequest)-[:PR_OPEN]- 
(pre:PullRequestEvent) 
<-[:DO]-(u2:User)<-[:OWNED_BY]-(f2:Fork)<-[:BRANCH_OF]-(br:Branch)<- 
[:FROM_BRANCH]-(pr2:PullRequest) 
WHERE u = u2 AND fork = f2 AND pr = pr2 
RETURN count(p), avg(pre.time - fe.time) as offsetTime

More Related Content

PDF
Puppet Data Mining
PDF
Prototyping in the cloud
PPTX
Retrofit 2 - O que devemos saber
PDF
Tupperware
PDF
Puppet and Openshift
ODP
Practical git for developers
DOCX
Git setuplinux
PDF
How Do I Contribute?
Puppet Data Mining
Prototyping in the cloud
Retrofit 2 - O que devemos saber
Tupperware
Puppet and Openshift
Practical git for developers
Git setuplinux
How Do I Contribute?

What's hot (20)

KEY
Gittalk
PDF
Git Basics (Professionals)
PDF
Infinum Android Talks #16 - Retrofit 2 by Kristijan Jurkovic
PDF
ćć€ć±‹SGGAE/Jć‹‰ćŒ·äŒš Grails、Gaelykでハンă‚șă‚Șン
PDF
Git: An introduction of plumbing and porcelain commands
 
PDF
IntroducciĂłn a git y GitHub
PPTX
Python from zero to hero (Twitter Explorer)
PPTX
Introduction To Git Workshop
PPTX
10 tips for making Bash a sane programming language
PDF
Asynchronous CompletableFuture Presentation by LĂĄszlĂł-RĂłbert Albert @Crossover
PDF
Git real slides
PDF
Nginx3
PPTX
2012 coscup - Build your PHP application on Heroku
PDF
Puppet camp Portland 2015: -windows (1)
 
PDF
The async/await concurrency pattern in Golang
PDF
G*ăȘă‚Żăƒ©ă‚Šăƒ‰ é›ČぼかăȘăŸă«ïœž
PDF
My Notes from https://www.codeschool.com/courses/git-real
PDF
DOCX
Git github
PDF
How to send gzipped requests with boto3
Gittalk
Git Basics (Professionals)
Infinum Android Talks #16 - Retrofit 2 by Kristijan Jurkovic
ćć€ć±‹SGGAE/Jć‹‰ćŒ·äŒš Grails、Gaelykでハンă‚șă‚Șン
Git: An introduction of plumbing and porcelain commands
 
IntroducciĂłn a git y GitHub
Python from zero to hero (Twitter Explorer)
Introduction To Git Workshop
10 tips for making Bash a sane programming language
Asynchronous CompletableFuture Presentation by LĂĄszlĂł-RĂłbert Albert @Crossover
Git real slides
Nginx3
2012 coscup - Build your PHP application on Heroku
Puppet camp Portland 2015: -windows (1)
 
The async/await concurrency pattern in Golang
G*ăȘă‚Żăƒ©ă‚Šăƒ‰ é›ČぼかăȘăŸă«ïœž
My Notes from https://www.codeschool.com/courses/git-real
Git github
How to send gzipped requests with boto3
Ad

Viewers also liked (11)

PPTX
Graph Database Prototyping made easy with Graphgen
ODP
GMDSS - Practice1
PPTX
Management des issues Github avec Neo4j et NLP
KEY
Présentation symfony drupal
PDF
Neo4j au secours de l'Internet of Connected Things
PDF
Recommendation Engines with Neo4j, Symfony and Reco4PHP
PPTX
Graphgen - le générateur de graphes
PDF
20161020 - Paris - Retour GC
PDF
Your own recommendation engine with neo4j and reco4php - DPC16
PDF
Moteurs de recommendation avec Neo4j et GraphAwareReco
PDF
Recommandations avec Neo4j et le GraphAware Recommendation Engine
Graph Database Prototyping made easy with Graphgen
GMDSS - Practice1
Management des issues Github avec Neo4j et NLP
Présentation symfony drupal
Neo4j au secours de l'Internet of Connected Things
Recommendation Engines with Neo4j, Symfony and Reco4PHP
Graphgen - le générateur de graphes
20161020 - Paris - Retour GC
Your own recommendation engine with neo4j and reco4php - DPC16
Moteurs de recommendation avec Neo4j et GraphAwareReco
Recommandations avec Neo4j et le GraphAware Recommendation Engine
Ad

Similar to Analysing Github events with Neo4j (20)

PDF
SQLGitHub - Access GitHub API with SQL-like syntaxes
PDF
The Future of Sharding
 
PDF
Beginner Apache Spark Presentation
PPTX
Project Deimos
PPT
Mozilla - Anurag Phadke - Hadoop World 2010
PPTX
A Game of Data and GraphQL
 
PDF
Cypher and apache spark multiple graphs and more in open cypher
 
PDF
Near Realtime Processing over HBase
PDF
A document-inspired way for tracking changes of RDF data - The case of the Op...
PDF
Ensuring Quality in Data Lakes (D&D Meetup Feb 22)
 
PPTX
Neo4p dcbpw-2015
PDF
Msr2021 tutorial-di penta
PPTX
Big Data Day LA 2015 - Compiling DSLs for Diverse Execution Environments by Z...
PDF
Approximate Queries and Graph Streams on Apache Flink - Theodore Vasiloudis -...
PDF
Approximate queries and graph streams on Flink, theodore vasiloudis, seattle...
PDF
The BIG List of GitHub Search Operators
PPTX
Cloud computing major project
 
PDF
OpenCog Developer Workshop
PPT
Temporal PPT details about the platform and its uses
PDF
Decentralized Evolution and Consolidation of RDF Graphs
SQLGitHub - Access GitHub API with SQL-like syntaxes
The Future of Sharding
 
Beginner Apache Spark Presentation
Project Deimos
Mozilla - Anurag Phadke - Hadoop World 2010
A Game of Data and GraphQL
 
Cypher and apache spark multiple graphs and more in open cypher
 
Near Realtime Processing over HBase
A document-inspired way for tracking changes of RDF data - The case of the Op...
Ensuring Quality in Data Lakes (D&D Meetup Feb 22)
 
Neo4p dcbpw-2015
Msr2021 tutorial-di penta
Big Data Day LA 2015 - Compiling DSLs for Diverse Execution Environments by Z...
Approximate Queries and Graph Streams on Apache Flink - Theodore Vasiloudis -...
Approximate queries and graph streams on Flink, theodore vasiloudis, seattle...
The BIG List of GitHub Search Operators
Cloud computing major project
 
OpenCog Developer Workshop
Temporal PPT details about the platform and its uses
Decentralized Evolution and Consolidation of RDF Graphs

Recently uploaded (20)

PDF
Digital Systems & Binary Numbers (comprehensive )
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
2025 Textile ERP Trends: SAP, Odoo & Oracle
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PDF
Softaken Excel to vCard Converter Software.pdf
PPTX
Introduction to Artificial Intelligence
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PDF
wealthsignaloriginal-com-DS-text-... (1).pdf
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PDF
System and Network Administration Chapter 2
PPT
Introduction Database Management System for Course Database
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PPTX
history of c programming in notes for students .pptx
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
Digital Systems & Binary Numbers (comprehensive )
Adobe Illustrator 28.6 Crack My Vision of Vector Design
Wondershare Filmora 15 Crack With Activation Key [2025
2025 Textile ERP Trends: SAP, Odoo & Oracle
Internet Downloader Manager (IDM) Crack 6.42 Build 41
Odoo Companies in India – Driving Business Transformation.pdf
Softaken Excel to vCard Converter Software.pdf
Introduction to Artificial Intelligence
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
wealthsignaloriginal-com-DS-text-... (1).pdf
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
System and Network Administration Chapter 2
Introduction Database Management System for Course Database
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
Design an Analysis of Algorithms II-SECS-1021-03
How to Migrate SBCGlobal Email to Yahoo Easily
history of c programming in notes for students .pptx
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf

Analysing Github events with Neo4j

  • 2. #whoami ‱ Christophe Willemsen ‱ Bruges (Belgium) ‱ Created Graphgen (graphgen.neoxygen.io) ! ! ! ! ‱ @ Graph Aware
  • 4. #github-data-archive ‱ Github Events ‱ archive available @ http://www.githubarchive.org/ ‱ events json files per hour ‱ approx. 10k events per hour ‱ ! the file in itself is not valid json, all file rows are valid json
  • 5. #event-types ‱ CommitCommentEvent ‱ CreateEvent ‱ DeleteEvent ‱ DeploymentEvent ‱ DeploymentStatusEvent ‱ DownloadEvent ‱ FollowEvent ‱ ForkEvent ‱ ForkApplyEvent ‱ GistEvent ‱ GollumEvent ‱ IssueCommentEvent ‱ IssuesEvent ‱ MemberEvent ‱ PageBuildEvent ‱ PublicEvent ‱ PullRequestEvent ‱ PullRequestReviewCommentEvent ‱ PushEvent ‱ ReleaseEvent ‱ StatusEvent ‱ TeamAddEvent ‱ WatchEvent
  • 6. #gh4j Github Events importer for Neo4j Parse file + build customized Cypher Statements for each event + load in Neo4j
  • 7. #PullRequestEvent Payload and informations from the past ‱ You get information of the PR ‱ You can also build informations about the repo, who is owning it for e.g. ‱ On which branch ‱ Depending of the P.R. Action (open/close/merge), you can determine for a close/merge who opened first the PR and from which fork it is coming
  • 8. MERGE (u:User {name:'pixelfreak2005'}) CREATE (ev:PullRequestEvent {time:toInt(1401606356) }) MERGE (u)-[:DO]->(ev) MERGE (pr:PullRequest {html_url:'https://github.com/pixelfreak2005/liqiud_android_packages_apps_Settings/pull/2'}) SET pr += { id:toInt(16573622), number:toInt(2), state:'open'} MERGE (ev)-[:PR_OPEN]->(pr) MERGE (ow:User {name:'pixelfreak2005'}) MERGE (or:Repository {id:toInt(20338536), name:'liqiud_android_packages_apps_Settings'}) MERGE (or)-[:OWNED_BY]->(ow) MERGE (pr)-[:PR_ON_REPO]->(or)
  • 9. #ForkEvent MERGE (u:User {name:'rudymalhi'}) CREATE (ev:ForkEvent {time:toInt(1401606379) }) MERGE (u)-[:DO]->(ev) CREATE (fork:Fork:Repository {name:'Full-Stack-JS-Nodember'}) MERGE (ev)-[:FORK]->(fork)-[:OWNED_BY]->(u) MERGE (bro:User {name:'mgenev'}) MERGE (br:Repository {id:toInt(15503488), name:'Full-Stack-JS-Nodember'})-[:OWNED_BY]->(bro) MERGE (fork)-[:FORK_OF]->(br)
  • 10. #IssueCommentEvent You can check if the issue is related to a P.R. and build the complete P.R. schema MERGE (u:User {name:'johanneswilm'}) CREATE (ev:IssueCommentEvent {time:toInt(1401606384) }) MERGE (u)-[:DO]->(ev) MERGE (comment:IssueComment {id:toInt(44769338)}) MERGE (ev)-[:ISSUE_COMMENT]->(comment) MERGE (issue:Issue {id:toInt(34722578)}) MERGE (repo:Repository {id:toInt(14487686)}) MERGE (comment)-[:COMMENT_ON]->(issue)-[:ISSUE_ON]->(repo) SET repo.name = 'diffDOM' MERGE (owner:User {name:'fiduswriter'}) MERGE (comment)-[:COMMENT_ON]->(issue)-[:ISSUE_ON]->(repo)-[:OWNED_BY]->(owner)
  • 11. Let’s have some fun and try some queries ! demo
  • 12. who did the most events ? ! MATCH (u:User)-[r:DO]->() RETURN u.name, count(r) as events ORDER BY events DESC LIMIT 1
  • 13. which repo has been the most touched ? ! MATCH (repo:Repository)<-[r]-() RETURN repo.name, count(r) as touchs ORDER BY touchs DESC LIMIT 1
  • 14. which repo has been the most forked ? ! MATCH (repo:Repository)<-[:FORK_OF]-(fork:Fork)<-[:FORK]- (event:ForkEvent) RETURN repo.name, count(event) as forks ORDER BY forks DESC LIMIT 1
  • 15. which repo has the most merged PRs ? ! MATCH (repo:Repository)<-[:PR_ON_REPO]- (pr:PullRequest)<-[merge:PR_MERGE]-() RETURN repo.name, count(merge) as merges ORDER BY merges DESC LIMIT 1
  • 16. how much forks are resulting in an open PR ? ! MATCH p=(u:User)-[:DO]->(fe:ForkEvent)-[:FORK]->(fork:Fork) -[:FORK_OF]->(repo:Repository)<-[:PR_ON_REPO]-(pr:PullRequest) -[:PR_OPEN]-(pre:PullRequestEvent)<-[:DO]-(u2:User)<-[:OWNED_BY]- (f2:Fork)<-[:BRANCH_OF]-(br:Branch)<-[:FROM_BRANCH]-(pr2:PullRequest) WHERE u = u2 AND fork = f2 AND pr = pr2 RETURN count(p)
  • 18. Number of comments on a PR before the PR is merged ? ! MATCH p=(ice:IssueCommentEvent)-[:ISSUE_COMMENT]->(comment:IssueComment) -[:COMMENT_ON]->(issue:Issue)-[:BOUND_TO_PR]->(pr:PullRequest) <-[:PR_MERGE]-(pre:PullRequestEvent) WHERE ice.time <= pre.time WITH pr, count(comment) as comments RETURN avg(comments)
  • 19. Top contributor ? Which user has the most merged PR’s on repositories not owned by him ! MATCH (u:User)-[r:DO]->(fe:PullRequestEvent)-[:PR_OPEN]->(pr:PullRequest {state:'merged'}) -[:PR_ON_REPO]-(repo:Repository)-[:OWNED_BY]->(u2:User) WHERE NOT u = u2 RETURN u.name, count(r) as prs ORDER BY prs DESC LIMIT 1
  • 20. Relate together Users having Merged PR's on same repositories, could serve as Follow Recommendations Engine! ! MATCH p=(u:User)-[:DO]-(e:PullRequestEvent)-->(pr:PullRequest {state:'merged'})- [:PR_ON_REPO]->(r:Repository)<-[:PR_ON_REPO]-(pr2:PullRequest {state:'merged'})--(e2:PullRequestEvent)<-[:DO]-(u2:User) WHERE NOT u = u2 WITH nodes(p) as coll WITH head(coll) as st, last(coll) as end MERGE (st)-[r:HAVE_WORKED_ON_SAME_REPO]-(end) ON MATCH SET r.w = (r.w) + 1 ON CREATE SET r.w = 1
  • 22. ‱ More queries in the gist file : https://gist.github.com/ikwattro/ 071d36f135131e8e4442 ‱ Not valid with Github Live API (different payload) ‱ zipped db file http://bit.ly/1BaMCy9
  • 24. avg time between a repo is forked and this fork result in an opened PR ? ! MATCH p=(u:User)-[:DO]->(fe:ForkEvent)-[:FORK]->(fork:Fork)-[:FORK_OF] ->(repo:Repository)<-[:PR_ON_REPO]-(pr:PullRequest)-[:PR_OPEN]- (pre:PullRequestEvent) <-[:DO]-(u2:User)<-[:OWNED_BY]-(f2:Fork)<-[:BRANCH_OF]-(br:Branch)<- [:FROM_BRANCH]-(pr2:PullRequest) WHERE u = u2 AND fork = f2 AND pr = pr2 RETURN count(p), avg(pre.time - fe.time) as offsetTime