Neo4j

Neo4j 圖型化資料庫入門

何家瑋 2020/12/14 17:41:58
121

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/

 

何家瑋