Neo4j 圖型化資料庫入門
Neo4j 是目前圖型化資料庫中最受歡迎的,在DB-ENGINES ranking 中長期名列前矛,近年台灣也有政府機關及企業團體慢慢導入Neo4j的技術,本篇將介紹Community 版本的基礎入門
系統需求
1. 使用x86-64架構的硬體環境
2. 4.0版本需Java 11.0 或 openJDK 11以上
安裝
第一種安裝方式:
至官網下載Neo4j Community Edition 4.2.1
https://neo4j.com/download-center/#community
解壓縮後移至該目錄下
要將Neo4j作為控制台應用程序,輸入以下
C:\neo4j-community-4.2.1\bin>neo4j console
要將Neo4j安裝為服務執行,則輸入
C:\neo4j-community-4.2.1\bin>neo4j install-service
訊息出現started表示成功啟動
開啟瀏覽器輸入 http://localhost:7474/
預設使用者及密碼為neo4j/neo4j,初次啟動變更密碼後即可進入管理頁面
第二種安裝方式:
下載Neo4j Desktop 1.3.11
https://neo4j.com/download-center/#desktop
Neo4j Desktop是官方推出的管理app,適用於windows、Mac、具有GUI的linux系統
內容整合了JRE、Neo4j Database、Neo4j browser(介面與透過瀏覽器進入相同)、Neo4j Bloom(探索分析軟體)、ETL tool及其他App
因內含JRE,故無需另外安裝JAVA JDK,是一個方便的好選擇
建立資料
首先建立一個官方的範例資料庫
於命令列輸入
:play movie-graph
會出現新增資料庫的基本教學卡片,內容是一些電影、導演、演員等相關資料
點選說明欄的圖示,便會自動產生Neo4j專用的語法Cypher
由於community 4.2版之後已不支援使用者新建資料庫,故跳過第一步這個指令
直接將資料新增於預設Database-neo4j之中(原範例為新增至新建的Database - movies之中)
進入第二頁後,點選下圖綠框可產生新增資料的語法
按下enter後即完成新增資料,並可看見剛剛新增的一部份內容
Cypher語法簡介
Cypher是Neo4j專用的查詢語法,是一種宣告式的查詢語言,並遵循SQL語法,最大的優點是可讀性非常高,而且簡單易學
在開始探索資料庫前,先學習如下使用Neo4j的專用語法Cypher
結構
最基本的節點與關係表示法如下圖所示,用括弧()表示節點,用中括弧[]表示關係
變數為非必需,節點的標籤與關係的類別要在前方加入冒號,兩者的屬性位於標籤或類別後方的大括弧,為key-Value結構
ID為該節點或關係的唯一識別碼,於新增時由DB自行產生流水號,無法修改
常用命令
CYPER 命令 | 作用 |
CREATE | 建立節點、關係或是屬性 |
MATCH | 查詢相符的節點、關係 |
RETURN | 返回查詢結果 |
SET | 更新屬性、標籤或是關係種類 |
MERGE | 查詢相符的節點、關係,若不存在則新增 |
WHERE | 設定過濾查詢條件 |
REMOVE | 刪除屬性 |
DELETE | 刪除節點、關係或是查詢結構內的所有節點及關係 |
ORDER BY | 設定查詢結果的排序條件 |
以下介紹範例
1. CREATE
// 新增一個Label為Animal,且帶有一個name為Lion的屬性
CREATE (n:Animal{name:'Lion'})
// 新增兩個空節點,兩節點有著單向關係:KNOW
CREATE ()-[:KNOWS]->()
// 新增兩個無標籤節點,一個有著name為Tom的屬性,另一個有著name為Mary的屬性,兩節點有著由Tom指向Mary的關係:Friend,並有著since為2012的屬性
CREATE ({name:'Tom'})-[:Friend {since:2012}]->({name:'Mary'})
2. MATCH 及 RETURN
// 查詢剛剛新增的節點並回傳
MATCH (n:Animal{name:'Lion'})
RETURN n;
// 我們可以指定查詢的結構並回傳,下例為查詢Tom與Mary中間僅有一層關係的結構
MATCH pattern=({name:'Tom'})-[]-({name:'Mary'})
RETURN pattern;
3. SET
// 為剛剛新增Lion新增一個屬性:age=10
MATCH (n:Animal{name:'Lion'})
SET n.age=10;
// SET可用時用於更新,將剛剛Lion的age更正為8
MATCH (n:Animal{name:'Lion'})
SET n.age=8;
// 為剛剛新增的Tom與Mary新增person的標籤
MATCH (m{name:'Tom'}),(n{name:'Mary'})
SET m:person, n:person;
4. MERGE
// 使用MERGE會先查詢是否存在,若不存在則會新增,下面例子再建立一個Tom的朋友John
MERGE (m:person{name:'Tom'})-[:Friend {since:2009}]->(n:person{name:'John'});
5.WHERE
// 現在為止我們已經建立了3個person節點,透過WHERE把Mary查詢出來
MATCH (n:person)
WHERE n.name = 'Mary'
RETURN n;
6. REMOVE
// 試著刪除Lion的age屬性
MATCH (n:Animal{name:'Lion'})
REMOVE n.age;
7. DELETE
// 試著刪除Lion這個節點
MATCH (n:Animal{name:'Lion'})
DELETE n;
8. ORDER BY
// 將查詢的資料透過ORDER BY進行排序,雖然圖面無法看出排序,但會反應在透過HTTP API接收到的response
// 或是回傳資料為RowSet的文字型式時,便能在管理介面直接看出
MATCH (n:person) RETURN n ORDER BY n.name
探索資料
對cypher有了基本的概念後,回到剛剛的教學卡片,進入第三、四頁,可以看見一些基本的教學語法
下面介紹一些簡單的範例
於剛剛新增的電影資料庫中尋找演員Tom Hanks
MATCH (tom {name: "Tom Hanks"}) RETURN tom
將滑鼠游標移至Tom Hanks的節點(node)上,左下角會顯示這個節點的屬性(property)
可以看到Tom Hanks的ID為71,是此節點的唯一識別碼,另外還可看到出生年份為1956年
接著尋找名為Tom Hanks曾經飾演過的電影
MATCH (tom:Person {name: "Tom Hanks"})-[:ACTED_IN]->(tomHanksMovies) RETURN tom,tomHanksMovies
左上角可以看見可節點的種類,橘色的節點為person,藍色的節點為movie
所以從回傳結果可以看到,Tom Hanks總共飾演[:ACTED IN]了12部電影
其中That Thing You Do這部電影同時也由Tom Hanks執導[:DIRECTED]
接著我們執行一些較為複雜的查詢
找出有哪些演員曾和Tom Hanks一起演出,並且比Tom Hanks年長,分別是哪些電影?
MATCH p=(tom:Person {name:"Tom Hanks"})-[:ACTED_IN]->(m)<-[:ACTED_IN]-(coActors)
WHERE coActors.born < 1956
RETURN p
反向搜尋是圖型化資料庫最強大的地方,相較於傳統的RDB資料庫需要非常複雜的SQL才能辦到,在Neo4j中卻能以簡單的Cypher達成
試著執行一個反向搜尋:詢與Tom Hanks一起演出的演員中,曾經與Tom Cruise共同演出的電影及關係圖
MATCH (tom:Person {name:"Tom Hanks"})-[:ACTED_IN]->(m)<-[:ACTED_IN]-(coActors),
(coActors)-[:ACTED_IN]->(m2)<-[:ACTED_IN]-(cruise:Person {name:"Tom Cruise"})
RETURN tom, m, coActors, m2, cruise
接著查詢一些只有在圖型化資料庫才會看見的查詢
我們想要知道Kevin Bacon和Meg Ryan這兩位演員最短的關係路徑為何
MATCH p=shortestPath(
(bacon:Person {name:"Kevin Bacon"})-[*]-(meg:Person {name:"Meg Ryan"})
)
RETURN p
從回傳結果可以看到,Kevin Bacon與Tom Hank共同演出Apollo 13,而Meg Ryan也與Tom Hank共同演出Sleepless
因此,Kevin Bacon => Apollo 13 => Tom Hank => Sleepless => Meg Ryan 即是兩人之間的最短關係路徑
接著來查詢與Kevin Bacon的關係層數在4層以下的所有人物及電影:
MATCH (bacon:Person {name:"Kevin Bacon"})-[*1..4]-(hollywood)
RETURN DISTINCT hollywood
查詢結果不限於節點或是關係,也可僅回傳某個屬性
例如查詢曾與Tom Hanks共演過的演員姓名,並且按照演員姓名排序
MATCH (tom:Person {name:"Tom Hanks"})-[:ACTED_IN]->(m)<-[:ACTED_IN]-(coActors)
RETURN coActors.name
ORDER BY coActors.name;
參考資料
https://neo4j.com/docs/operations-manual/4.2/
https://neo4j.com/docs/cypher-manual/current/
Thank you.