原文链接:https://tbgraph.wordpress.com/2017/06/10/neo4j-marvel-social-graph/
译者言,本文通过构建漫威世界中各英雄之间一起出现在漫画中的次数,计算出了漫威世界中最重要的英雄。在Cypher语法的使用方面,着重介绍了数据导入LOAD CSV、批处理方法apoc.periodic.iterate、以及MERGE语句。
今天我将会演示如如何将漫威世界的数据导入到Neo4j中,同时我将使用一个非常简单的模型,展示出使用图数据库去存储社交网络数据有哪些优越性。
基本要求
- Neo4j(https://neo4j.com/download/)
- Apoc插件(https://github.com/neo4j-contrib/neo4j-apoc-procedures/releases)
数据
我们需要的漫威社交数据(https://www.kaggle.com/csanhueza/the-marvel-universe-social-network)可以从kaggle竞赛的一个贴子中获取。数据里有3个csv文件:
- nodes.csv --结点名称与类型。
- edges.csv --英雄与漫画之间的关系。
- hero-network.csv --在同一部漫画中英雄之间的关系。
我们只需要edges.csv文件,就可以知道每位英雄出现在对应的哪部漫画中,这对于我们社交网络构建就足够了。暂时不需要hero-network.csv文件,因为我们可以使用cypher或apoc去构建我们自己的、带有权重的各英雄之间关系。
图模型
我们使用一个非常简单的图模型:两个标签Hero和Comic,以及这两个标签中一个关系APPEARED_IN。
数据导入
首先我们在Comic和Hero标签上创建约束,可以使查询的速度更快。
CALL apoc.schema.assert({},{Comic:['name'],Hero:['name']});
我已经上传了edges.csv文件到github代码库中,你可以使用下面的语句一步导入。导入语句也非常简单,只是使用MERGE语句进对结点和关系进行合并,当大数据里需要进行导入时,需要使用USING PERIODIC COMMIT语句进行批处理设置。
USING PERIODIC COMMIT 5000LOAD CSV WITH HEADERS FROM "https://raw.githubusercontent.com/tomasonjo/neo4j-marvel/master/data/edges.csv" as rowMERGE (h:Hero{name:row.hero})MERGE (c:Comic{name:row.comic})MERGE (h)-[:APPEARED_IN]->(c)
创建带有权重的无方向性的英雄间关系网络
现在已经导入数据了,我们要创建一个带权重的英雄社交网络,我们假设所有漫画英雄他们彼此认识,使用KNOWS关系进行表示,且把他们在漫画世界中一起出现同一本漫画中的次数做为KNOWS关系的weight属性值。
译者言:“weight属性值”指在一本漫画中,有两位英雄出现了,则两位英雄之间的KNOWS关系的weight为1;如在两本漫画中都出现,则两位英雄之间的weight为2。 这个一定要理解清楚,因为后面的分析都要基于这个属性来完成。
语言表达能力还有待提高,如果有不理解的,欢迎留言讨论。
由于我们的关系图挺大的, 在一个事务中进行全局性的计划不太可能,所以我们需要分批来处理,此时,在Cypher查询中使用APOC库,进行分批处理是再合适不过了,而APOC库中的 apoc.periodic.iterate 方法正是为此而生。
译者言:关于高性能数据插入这块可以看这篇文章(https://blog.csdn.net/hwz2311245/article/details/60963383),介绍的相当不错。
下面节选自APOC官方文档
apoc.periodic.iterate 方法需要提供两个参数,第一个参数是外部语句,将提供一个数据流,表示哪些数据将会被处理。第二个参数是内部语句,通过参数itertaList:true来进行控制,表示一次处理一个元素或一次处理一批元素。 (译者言:后面将会详细介绍apoc.periodic.iterate 方法)
我们将使用下面语句创建一个有权重的无方向性的英雄社交网络
CALL apoc.periodic.iterate("MATCH (p1:Hero)-->(:Comic)