kwattro/gh4j

使用Neo4j进行GitHub仓库分叉分析

安装: 11

依赖项: 0

建议者: 0

安全: 0

星标: 7

关注者: 2

分叉: 1

类型:应用程序

dev-master 2014-07-25 00:00 UTC

This package is not auto-updated.

Last update: 2024-09-10 07:25:29 UTC


README

轻松将GitHub事件数据归档导入Neo4j图数据库

免责声明!

由于事件负载完全不同,该工具不兼容GitHub ReST API。不过,它可以作为一个沙盒,以便将来切换到API。

是什么?

这是一个简单的库,可以解析GitHub事件归档文件并将这些事件加载到Neo4j图数据库中。

它包含一个简单的数据加载入口点和一些EventType加载器,这些加载器将生成插入数据所需的Cypher查询。此库与一个简单的连接库耦合,以访问Neo4j ReST API。

它还会创建事件、仓库、用户、分叉和评论之间的关系,以便您可以全面了解GitHub上发生的事情以及它们是如何相关的。

注意/Achtung/Ola

此库主要作为一个个人实验制作,查询将生成的数据库模式适合于我打算处理数据的方式,我并不声称这是最佳模式,但它是与Neo4j图数据库玩耍的良好练习。

当然,建议、观点、PR等总是受欢迎的。

NB:提醒一下,GitHub上每小时大约有8000个事件

如何使用

1. 在您的项目依赖关系中要求Gh4j

将以下要求添加到您的composer.json文件中

"require":{
	// ..... other dependencies
	"kwattro/gh4j" : "dev-master"
}

2. 实例化Gh4j

require 'vendor/autoload.php';

use Kwattro\Gh4j\Gh4j;

$gh = new Gh4j();

下载GitHub事件数据归档

您可以在GitHub归档网站上下载数据归档。只需遵循说明,下载您想要期间的数据。

在您的计算机上某处解压缩下载的文件。

4. 将数据加载到数据库中

下载文件不是有效的JSON,但包含表示Event发生的有效JSON的行。

使用PHP的file函数,您将获得一个数组格式,其中每行包含JSON事件对象,循环遍历数组并加载事件。

$events = file('/Users/kwattro/gh/data/2014-06-01-3.json', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);

foreach ($events as $event) {
	$gh->loadEvent($event);
}

然后,Gh4j库将检查JSON的有效性,加载适当的EventType加载器并将数据插入数据库。

默认情况下,每次调用loadEvent()将触发与数据库的连接以插入数据。您可以使用Stack方法累积*数量的查询,并在达到指定限制时刷新。

要使用它,您需要通过提供true作为第二个参数来指示加载方法使用stackMethod。

// Code to read your file ....
foreach ($events as $event) {
	$gh->loadEvent($event, true);
}
// Don't forget to flush after the loop to insert remaining queued queries
$gh->flush();

这将累积查询,直到达到限制,然后发送一个大的查询。以50为限制,这比每次调用数据库快2倍,对于包含大约8000个事件的文件,在50秒内插入(1小时文件)。

您可以通过访问数据库连接器来调整stack的限制。

$gh = new Gh4j():
$conn = $gh->getConnector();
$conn->setStackFlushLimit(30); // Stack will be flushed after 30 queries

支持的事件类型

目前有4种事件类型被处理

  • PushEvent
  • PullRequestEvent
  • ForkEvent
  • IssueCommentEvent

每种类型都将由一个自定义事件加载器处理,该加载器扩展了BaseEventLoader,该加载器为事件的常见负载创建Cypher查询。

建议您查看EventLoader目录内的代码注释,以了解数据如何插入,或者查看本README文件的“生成的Cypher查询”部分。

如果在数据中遇到不支持的EventType,它将被跳过。

更多内容即将到来...

生成的Cypher查询示例

PushEvent

MERGE (u:User {name:'ZhukV'}) CREATE (ev:PushEvent {time:toInt(1401606330) }) MERGE (u)-[:DO]->(ev) 
MERGE (repo:Repository {id:toInt(20051270)}) 
SET repo.name='Unicode' 
MERGE (branch:Branch {ref:'refs/heads/master', repo_id:toInt(20051270)}) 
MERGE (ev)-[:PUSH_TO]->(branch) 
MERGE (branch)-[:BRANCH_OF]->(repo) 
MERGE (owner:User {name:'ZhukV'}) 
MERGE (repo)-[:OWNED_BY]->(owner) 

Expl

-> 匹配或创建执行事件的用户 -> 将用户与该事件关联 -> 匹配或创建推送到该用户的仓库 -> 匹配或创建推送到该用户的分支 -> 事件与分支相关联为PUSH_TO -> 分支是仓库的BRANCH_OF -> 匹配或创建仓库的所有者 -> 由某人拥有的仓库

PullRequestEvent

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

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)

我倾听所有能提高查询性能的建议:)