知识图谱_Neo4j的建模和数据加载 记录

根据(thirsd的个人空间 - 哔哩哔哩 ( ゜- ゜)つロ 乾杯~ Bilibili)整理

一、图建模

根据建模的目标确定需要解答的问题列表,设计一个模型来帮你解答这些问题,如果无法解答,继续优化模型。

图模型,可以参考行业或其他已经建立的模型:

neo4j.com/graphgists

neo4j.com/sandbox

二、cypher示例

查询示例:

match (node:Entity {key:value} )
where node.otherkey < 5
match (node)-[:REL]->(other:Thing)
with node, collect(other.name) as others
where size(others) > 10
return *

更新示例:

load csv from "url" as row
create (from:Entity {id:row.source})
set from.key = toInteger(row.fromKey)
Merge (to:Thing {id:row.target})
on create set to.value = toFloat(row.value)
Merge (from)-[:REL]->(to)
Remove to.tmp
set from:Processed

执行函数

call procedure.name("param", 10)
yield key as id, value as user
where id > 10 and function.name(user, "abc") = 5
return id, user

创建索引和约束

# 为label的property创建索引
create index on :labe(property);
# 为label的property的创建唯一性约束
create constraint on (n:label) assert n.property is Unique;
# 为label创建property存在约束
create constraint on (n:label) assert exists(n.property);
# 为关系创建property存在约束
create constraint on (:label) -[r:REL]->(:label) assert exists(r.property);                             

三、高效查询和导入

对于在MATCHMERGE 中使用属性值得情况,建议通过索引和约束来提高查询效率。

3.1 neo4j如何使用索引

仅当查询起始节点时才会使用索引

创建neo4j的schema:

create constraint on (u:User) assert u.id is unique;
create constraint on (b:Business) assert b.id is unique;
create constraint on (r:Review) assert r.id is unique;
create constraint on (c:Category) assert c.id is unique;

create index on :Bussiness(location);
create index on :Bussiness(city);
create index on :Review(date);

3.2 导入数据

将json转为csv,可以使用jq(一款用于处理json的轻量级的命令行)

导入时,

1、拷贝csv文件至import的目录下

2、csv是字符型,需要转换为数据目标格式

数字类型:toInteger(row.num), toFloat(row.money),

​ 布尔型:case row.action when "buy" then true else false end

​ 日期时间:date(row.date), datetime(row.time)

​ 位置:point({x:toFloat(row.at), y:toFloat(row.lon)})

​ split(row,categories, ",")

方式一:原始导入

load csv with headers from "file://review.csv" as row
merge (b:business{id: row.business_id})
merge (u:user {id: row.user_id})
merge (r:review {id: row.review_id})
on create set r.stars = toInteger(row.stats), r.text = row.text
merge (r)-[:REVIEWS]->(b)
merge (u)-[rr:WROTE]->(r)
on create set rr.date = row.date

通过explain cypher_sql 可以查看cypher_sql 的执行计划,对于load命令也支持

方式二:多值传参/逐个导入

load csv with headers from "file:////user.csv" as row
merge (u:user{id:row.user_id})
on create set u.name = row.name,u.reviews =toInteger(row.review_count), u.date = date(row.yelping_since);
                                                                                      
load csv with headers from "file:///business.csv" as row
merge (b:Business {id: row.business_id})
on create set b.stars = toFloat(row.stars), b.reviews = toInteger(row.review_count), b.location = point(row{.latitude, .longitude}), b += row {.name, .address, .city, .state};
                                                                           load csv with headers from "file:///review.csv" as row
match (u:User {id: row.user_id})
match (b:Business {id: row.business_id})
create (r:Review {id: row.review_id})
    set r.stars = toInteger(row.starts), r.date = date(row.date), r.text = row.text
create (u)-[:WROTE]->(r)
create (r)-[:REVIEWS]->(b);           

执行多行cypher脚本的方法:

1、在neo4j的浏览器中,打开muti-line的编辑器开关

2、cat import/import_xxx.cypher | bin/cypher-shell

方式三:Periodic commit

USING PERIODic COMMIT 20000

load csv with headers from "file:////user.csv" as row
merge (u:user{id:row.user_id})
on create set u.name = row.name,u.reviews =toInteger(row.review_count), u.date = date(row.yelping_since);

方式四:apoc.load.json和apoc.periodic,iterate

检查json文件:

call apoc.load.json("file:///user.json")
yield value
return value limit 10;
                    
call apoc.load.json("file:///user.json")
yield value
return count(*);

加载json文件

call apoc.load.json("user.json")
yield value
with value limit 10000
merge (u:User {id:value.user_id})
on create set
    u.name = value.name,
    u.fans = value.fans
call apoc.load.json("file:///user.json")
yield value
with value limit 100
match (u:User {id: value.user_id})
unwind values.frineds as friend
merge (f:User {id:friend})
merge (u)-[:FRIEND]-(f)
call apoc.load.json("file:///business.json")
yield value
with value litmit 1000
merge (b:Business {id: value.business_id})
on create set b += value{.name, .review_count, .stars, .address, .state},
              b.location = point(value{.latitude,.longitude})     
with b, value.categories as ategories
unwind categories as cat
merge (c:Categroy {name:cat})
merge (b)-[:IN_CATEGORY]->(c)

以上方案存在以下问题:

1、单线程运行

2、事务必须在RAM中

解决方案:apoc.periodic.iterate,将一个事务切分为小批次并行运行

call apoc.periodic.iterate(
"call apoc.load.json('file:///user.json') yield value return value skip 1000 limit 200000",
"create (u:User {user_id: value.user_id}) set u.name, u += value{. review_count, .fans}",
{batchSize:10000, iterateList:true, parallel:true, concurrency:3}
);

apoc.periodic.iterate 可以导入json,类似的,也可以导入csv。

call apoc.periodic.iterate(
"load csv with headers from 'file:////user.csv' as row return row",
"merge (u:user{id:row.user_id}) on create set u.name = row.name,u.reviews =toInteger(row.review_count), u.date = date(row.yelping_since)",
{batchSize:10000, iterateList:true, parallel:true, concurrency:3}
);

注意:return row ,返回数据用于切分

batchsize 建议在10k-50k,iterateList建议默认打开。

方式五:第三方工具

./bin/neo4j-admin import 命令导入

[图片上传失败...(image-fdfcf1-1606033640638)]

[图片上传失败...(image-cafd0d-1606033640638)]

调用示例:

[图片上传失败...(image-61a82c-1606033640638)]

注意:

1、需要在导入后创建索引和约束

2、性能提升至100s可以导入上亿记录

3、确保有足够的内存和磁盘

4、csv文件可以是压缩文件、正则表达匹配方式从文件总读取

5、指定数据类型的格式

​ stars:int,is_active:boolean, types:string[], date:Date

​ header location:Point(WGS-84)

方式六:RDMS 导入工具:NEO4J ETL

适用于初始化导入

操作步骤:

1、配置并选择RDMS的数据源

2、选择目标的neo4j数据库

3、加载关系元数据

4、查看并编辑映射关系

5、导出Tables到csv,保存至import目录下

6、通过导入工具导入数据

7、导入结构错误可以使用apo.refactor来重构

方式七:使用pyton的neo4j-driver包来导入

方式八:其他的导入工具

​ knowbi-pentaho-pdi-neo4j-output

​ Talend Neo4j integration

​ Streamsets

​ GraphAware Databridge

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容