【知識圖譜】Neo4j 導入數據構建知識圖譜的三種方法

目錄

Neo4j數據導入5種方式

1、使用Cypher語言創建

1.1 創建節點【create】

1.2 修改節點的屬性

1.3 創建帶屬性值的節點

1.4 創建節點間的關係

1.5 其他操作命令

1.6 cypher查詢語言的使用規律

2、使用load csv導入數據

2.1 構建容器(非必須)

2.2 導入節點csv文件

2.3 創建索引並刪除重複節點

2.4 導入關係csv文件

3、使用neo4j-admin導入數據

3.1 數據導入前的準備工作

3.2 數據預處理

3.3 數據導入

3.4 查看知識圖譜

4、總結


Neo4j數據導入5種方式

neo4j的數據導入方式有很多,總結起來總共分爲以下5種:

  1. Cypher CREATE 語句,爲每一條數據寫一個CREATE
  2. Cypher LOAD CSV 語句,將數據轉成CSV格式,通過LOAD CSV讀取數據。
  3. 官方提供的Java API —— Batch Inserter
  4. 大牛編寫的 Batch Import 工具
  5. 官方提供的 neo4j-import 工具

物種方式的優缺點對比:

1、使用Cypher語言創建

1.1 創建節點【create】

第一種方式:  merge(n:洛杉磯湖人)     # 節點不存在,則創建,存在,則忽略。

第二種方式:  create(n:洛杉磯湖人)     # 不管節點存不存在,創建

效果就是,洛杉磯湖人這類的節點,一共被創建了兩次,因此,查詢的時候,會出現兩個Node。雖然上面我們創建了兩個節點,但是這兩個節點除了系統給的唯一id外,沒有其他屬性,下面我就基於這兩個節點,分別對它們進行“update”,賦予節點意義。

1.2 修改節點的屬性

首先:查詢ID等於21798的Node

match(n) where ID(n) = 21798 return n   
#  別忘了查詢節點,最後要return n返回節點.

其次:給該Node添加三個屬性,分別是label(節點標籤名),height(身高),position(場上位置)

neo4j查詢節點用:match   == 相當於關係型數據庫的select,相當於非關係數據庫mongodb的find

neo4j修改節點屬性用:set == 相當於關係型數據庫的update...set...

match(n) where ID(n) = 21798 set n.label='科比',n.height=198,n.position='得分後衛' return n

類似sql語句: update n set label = ‘科比’,height=198,position='得分後衛' where id = 21798

區別:關係型數據庫如果字段不存在的話會報錯,而NoSql數據庫neo4j,如果屬性字段不存在的話,就添加

執行後,效果如下:

1.3 創建帶屬性值的節點

我們使用create創建另一位湖人傳奇巨星奧尼爾這個節點,語句如下:

create(n:洛杉磯湖人{label:'奧尼爾',height:216,position:'中鋒'}) return n

效果如下:

1.4 創建節點間的關係

構成一條關係最基本的要素是要有兩個對象,放在neo4j圖庫中就是,兩個節點,一條邊,才能稱作是一個完整的關係。創建統一用create命令,而關係的創建,實際上和創建節點差不多,唯一區別就是,關係是有方向的,而且關係用‘[]’表示,而節點用'()'表示。

下面我給目前尚存在的兩個節點,科比和奧尼爾創建一條關係,關係的name叫“搭檔”,這種關係,不區分方向,因此,無所謂誰是startNode,誰是endNode。

match(n),(b) where n.label='科比' and b.label='奧尼爾'
create(n)-[r:搭檔{since:1996,des:'NBA史上最強OK組合',champion:3}]->(b) 
return n,r,b

解釋一下:

1、首先匹配找到節點n和b,也就是科比和奧尼爾代表的節點Node;

2、然後創建節點n到節點b的關係r,r有三個屬性,一個是從哪一年開始since,一個是關係描述des,另一個是合作拿過的冠軍數量champion;

3、最後返回n,r,b 完整節點之間的關係結果,table數據如下,總過三列:
 

最終,創建的graph圖效果如下:

1.5 其他操作命令

如果要修改關係的屬性,和修改節點的屬性一樣,修改關係的屬性也用set,如修改id等於12513的關係的屬性des爲“小飛俠&大鯊魚”的語句如下:

match(n)-[r]-(b) where ID(r) = 12513 set r.des='小飛俠&大鯊魚' return n,r,b

如果要刪除節點間的關係,刪除統一用命令delete,和刪除節點一樣,刪除關係的語句如下:

match(n)-[r]-(b) where n.label='科比' and b.label='奧尼爾' delete r return r

如果要查詢科比和奧尼爾之間的關係,則語句如下:

match(n)-[r]-(b) where n.label='科比' and b.label='奧尼爾' return n,r,b

如果要創建索引,語法:

CREATE INDEX ON :<label_name> (<property_name>)

爲節點標籤洛杉磯湖人基於屬性label創建索引,語句如下:

create index on:洛杉磯湖人(label)

刪除索引:

DROP INDEX ON :<label_name> (<property_name>)
drop index on:洛杉磯湖人(label)

1.6 cypher查詢語言的使用規律

其實使用cypher語言來查詢還是非常簡單的,因爲不管你查什麼,查的無外乎節點、關係、節點間的關係,用表達式表示就是:(n)-[r]-(b),掌握以下規律,你就可以快速掌握如何使用Cypher語言。

結合表達式:  match(n)-[r] -(b)

      如果查詢節點n                            就    return n

      如果查詢關係r                             就    return r

      如果查詢節點b                            就    return b

      如果查詢節點n和b之間的關係r    就    return n,r,b

      如果查詢帶條件                          就    where n.x = x,r.xx = xx,b.xxx = xxx

      如果修改屬性                             就     where.....   set ....

      如果刪除屬性                             就     where.....   remove .....

      如果刪除節點或關係                   就     where.....   delete n 或者 delete r  或者 delete b 或者 delete n , r , b

 

2、使用load csv導入數據

2.1 構建容器(非必須)

docker環境下安裝:這裏說明下,默認將容器的/data,/var/lib/neo4j/import目錄映射到宿主機。/data存儲的是數據,/var/lib/neo4j/import存儲的是你想要導入數據的

docker run \
    --publish=7474:7474 --publish=7687:7687 \
    --volume=/data/neo4j/data:/data \
    --volume=/data/neo4j/import:/var/lib/neo4j/import \
    --env=NEO4J_dbms_memory_pagecache_size=2G \
    --env=NEO4J_dbms_memory_heap_max__size=8G \
    --name=neo4j \
    -d neo4j 

初次進行大批量數據的導入有很多方式,但是每種方式都會有自己的侷限性。這裏是官網文檔

2.2 導入節點csv文件

通過cypher-shell命令行直接導入數據。這樣的方式,可以不停用neo4j服務,直接導入到庫中。

#load node csv 
USING PERIODIC COMMIT 1000
LOAD CSV WITH HEADERS FROM "file:/nodes.csv" AS csvLine
CREATE (c:Contact { mobile:csvLine.mobile, name:csvLine.name, updateTime:csvLine.updateTime, createTime:csvLine.createTime });

USING PERIODIC COMMIT 1000,是滿足1000條之後,提交一個事務,這樣能夠提高效率。

2.3 創建索引並刪除重複節點

導入節點之後,我們必然會導入關係。這裏就有個坑,如果你在node節點的庫裏,沒有創建index,那麼導入關係的時候,將會慢的要死。

# 創建索引之前,我們插入的節點數據有可能會有重複的情況,我們需要先清除一下重複數據。
MATCH (n:Contact) 
WITH n.mobile AS mobile, collect(n) AS nodes 
WHERE size(nodes) > 1 
FOREACH (n in tail(nodes) | DETACH DELETE n);
#創建索引
CREATE CONSTRAINT ON (c:Contact) ASSERT c.mobile IS UNIQUE;
CREATE INDEX ON :Contact(mobile);

2.4 導入關係csv文件

USING PERIODIC COMMIT 1000
LOAD CSV WITH HEADERS FROM "file:/rels.csv" AS csvLine
MATCH (c:Contact {mobile:csvLine.mobile1}),(c1:Contact {mobile:csvLine.mobile2})
CREATE (c)-[:hasContact]->(c1);

3、使用neo4j-admin導入數據

通過neo4j-admin方式導入的話,需要暫停服務,並且需要清除graph.db,這樣才能導入進去數據。而且,只能在初始化數據時,導入一次之後,就不能再次導入了。所以這種方式,可以在初次建庫的時候,導入大批量數據,等以後如果還需要導入數據時,可以採用上邊的方法。

3.1 數據導入前的準備工作

對於大規模的數據集,使用語句插入和load csv的時候往往非常緩慢,當需要插入大量三元組時,可以考慮使用Neo4j-import的方式。這種方式有許多注意點

# 三元組數據導入前的準備工作
1、傳入文件名的時候務必使用絕對路徑。
2、在執行指令之前務必保證Neo4j處於關閉狀態,如果不確定可以在Neo4j根目錄下運行./bin/neo4j status 查看當前狀態。
3、使用neo4j-admin import指令導入之前先將原數據庫從neo4j_home/data/databases/graph.db/中移除。
4、寫CSV文件的時候務必確保所有的節點的CSV文件的ID fileds的值都唯一、不重複。並且確保所有的邊的CSV文件的START_ID 和 END_ID都包含在節點CSV文件中。

3.2 數據預處理

neo4j-import官方要求的數據格式爲csv文件,主要就是分成兩個文件entity.csv 和relationship.csv。

其中entity.csv中包含了實體的id,實體的name,以及標籤LABEL,具體格式如下:

entity:ID,name,:LABEL
e0,GDP,my_entity
e1,PHP,my_entity
e2,李衝,my_entity
e3,perimenopausal syndrome,my_entity
e4,雁蕩山景區分散,東起羊角洞,西至鋸板嶺;南起筋竹溪,北至六坪山。,my_entity
e5,詞條(拼音:cí tiáo)也叫詞目,是辭書學用語,指收列的詞語及其釋文。,my_entity
e6,蘆葦茂密,結草爲蕩,my_entity
e7,麪粉,水,酵母,蘇打,my_entity
e8,先註冊先得的原則,my_entity
e9,解壓縮軟件,my_entity
e10,華碩電腦股份有限公司,my_entity

relationship.csv文件包含了起始節點id,結束節點id,關係的name,以及標籤LABEL,具體格式如下:

:START_ID,:END_ID,name,:TYPE
e48,e799,屬性,屬性
e191,e479,描述,描述
e641,e5,描述,描述
e641,e182,標籤,標籤
e237,e575,描述,描述
e237,e237,中文名,中文名
e237,e533,是否含防腐劑,是否含防腐劑
e237,e264,主要食用功效,主要食用功效
e237,e405,適宜人羣,適宜人羣

需要將導入的數據轉換成這樣的兩個格式的csv文件,才能夠導入Neo4j中。

3.3 數據導入

csv數據文件準備好後,可以通過執行以下腳本來實現數據導入:

#導入命令
# 停止neo4j服務
neo4j stop 
# 如果是Linux可以進入到databases目錄下刪除數據庫,windows直接刪除即可
cd /usr/local/Cellar/neo4j/3.5.0/libexec/data/databases
rm -rf graph.db
# 執行數據導入命令neo4j-admin
neo4j-admin import \
--database=graph.db
--nodes:phone="../phone_header.csv,phones.csv \
--ignore-duplicate-nodes=true \
--ignore-missing-nodes=true \
--relationships:call="../call_header.csv,call.csv"
# 重啓neo4j服務
neo4j start

出現類似於如下結果,表示導入成功:

結果顯示導入了841個節點(因爲1000原數據中的節點有重複的),1002個關係(實際數據條數爲1002),1682個屬性值。

3.4 查看知識圖譜

查看結果:導入完成之後,我們可以打開neo4j瀏覽器查看一下導入後的結果,打開http://localhost:7474/browser/

知識圖譜生成後,重啓Neo4j服務:

neo4j start

查看整個知識圖譜,使用查詢命令:

match(n) return n

查詢實體節點爲Google的所有對應的關係:

match(n:my_entity)-[r]->(b) where n.name='Google' return n,r,b

至此,neo4j-import導入大量數據就成功了。

4、總結

以上介紹了create、load csv、neo4j-admin三種主要的數據導入方式,Batch Inserter和 Batch Import相對用的不多,Batch Inserter是需要在Java中使用,Batch Import可以參考該鏈接,本文介紹的三種方式基本滿足了各種數量級別的數據導入構建知識圖譜的要求,總有一款適合你!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章