Blog Cover Image

Inspire you to have New thinking, Walk out your unique Road.

[後端技術研究] Amazon Neptune 圖資料庫 (Graph Database)學習和資料視覺化(Data Visualization)

Posted onDec 16, 2022

Graph Database

Amazon Neptune 圖資料庫 (Graph Database)學習和資料視覺化(Data Visualization)是我在公司這次的創新 Idea Sprint 的研究主題。

前言

我們公司每三個月都會有一個 Sprint 叫做創新 Idea Sprint,在這個 Sprint,工程師們可以去研究自己想要研究的技術,然後在 Sprint 結尾秀出自己的研究成果給大家看。

而這次的形式和以往有點不同,美國團隊那邊提出可以嘗試看看跨團隊合作,意思就是我們可以去找別的部門/團隊合作,然後一起研究技術,增進跨團隊的溝通能力,以及讓研究的技術更多樣化。

我覺得是很難得的機會,這次本來有在想要不要去問問美國團隊有沒有人要一起合作搞點什麼創新,但是我看他們的 Idea 版上沒什麼美國人的名字,所以我也不知道能找誰,在專案經理早了一週就開始詢問每個人的計畫,然後當時只是覺得

Neptune 這個名字看起來很 Cool,然後看到 Visualization (視覺化) 就覺得是不是又有前端可以開搞 XDD,我至從今年初開始學前端,就對一些視覺化的玩意兒有興趣。所以,就把我的名字填在那張 Idea 卡片下方。

然後就和另外一個台灣的團隊組員一起研究 AWS Neptune Service 和 Data Visualization,進而產生了這篇文章。

從第一家公司畢業後,我就很少寫後端技術相關的文章,我覺得我那時處於的技能層跟想寫的文章好像都太基礎了,會有很多後端大神寫的比我更好,所以近年來都沒有在撰寫後端技術的文章,不過這次有這個機會我也很高興,能在後端技術中分享些新技術的知識。

Objective

我們這次的主題叫做 Amazon Neptune 圖資料庫 (Graph Database)學習和資料視覺化(Data Visualization)

我跟另外一個組員對 Graph Database 完全是 0 經驗,我們有 2~3 週的時間,從 0 開始學習,然後到可以用 AWS 的 Neptune 服務作出一些初步的實作,所以這篇文章不會介紹到太困難的技術層面,然後所有的內容直接切重點。

文章內容大致如下:

  • 學習圖資料庫(Graph Database)的基本概念
    • NoSQL
    • Graph DB 存資料的概念: Nodes, Edges, Label, Properties
    • 處理資料的語言 Query Language: Gremlin
    • 關聯式資料庫(RDB) VS 圖資料庫(Graph DB)
  • 實作 Part
    • 開啟 Amazon Neptune 資料庫 + Jupyter Notebook
    • 用 Gremlin 語言做簡單的塞資料跟搜尋資料
    • 實現資料視覺化 (Data Visualization)
      • aws/graph-notebook
      • G.V()
      • Gremlify

你準備好了嗎?

基本概念 Basic Knowledge

大概掌握下面幾個抽象概念就可以大致上了解 Graph DB

  • NoSQL
  • Nodes, Edges, Label, Properties
  • Query Language
  • 關聯式資料庫(RDB) VS 圖資料庫(Graph DB)

NOSQL

首先,Graph DB 不是關聯式資料庫,他跟一般接觸到的關聯式資料庫像是 MySQL, PostgreSQL, SQLite 不是同一路的技術,就是說存取資料的方式會不同,畢竟資料庫就是存資料的地方,但並不是每個資料都適合像是關聯式資料庫那樣的表格式一筆一筆資料存取。

| | Type | Example | | ------------------- | -------------- | ----------------- | | NoSQL 資料庫 | Key-Value | Redis | | | Document-based | MongoDB | | | Column-based | BigTable | | | Graph-based | Neptune, Neo4j | | 關聯式資料庫(RDBMS) | Table-based | MySQL, PostgreSQL |

從上表來看就能知道 Graph DB 是一種 NoSQL 形式的資料庫,可以清楚知道他處在什麼位置什麼分類。

Nodes, Edges, Label and Property

再來介紹 GraphDB 存取資料的抽象概念,如果說關聯式資料庫的名詞是 Table, Column, Primery Key 跟 Foreign Key,那 Graph DB 的名詞就會是 Nodes, Edges, Label 和 Property。

來個表格整理一下

| Object | Description | Similar Concept | | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- | | Nodes | 可以想像成一個一個個體或物件,像是 Google 這個公司,Amy 這個女生,Chanel 的綠色邂逅香水 | 比較像是關聯式 Table 內的一筆一筆資料。 | | Edges | 給像是關聯/關係,連接個體之間的關聯,這是 Graph DB 主要的關鍵概念 | 有點像是 Foreign Key,但 Edges 實際上是真的把個體串起來。 | | Label | 是抽象的屬性概念,將 Nodes 集結然後作分類,比方說: 不同的公司 (Nodes) 屬於公司這個 Label,那 Google 就是一個 Node 但是隸屬於公司這個 Label。 | 比較像是 Table,相同類別的資料會存在同一張 Table,Label 很像 Table Name | | Properties | 屬性,存在於 Node 跟 Edge 裡,打個比喻的話,Amy 是一個 28 歲的女生,屬性就會是 年齡: 28 一個屬性, 性別:女第二個屬性,屬性可以設置很多個在同一個 Node 或 Edge 裡。 | 很像 Column 欄位的概念 |

以上就是大致 Graph DB 的資料抽象概念。

Query Langauge: Gremlin

再來是處理資料所使用的語言,可以和 Graph DB 溝通處理資料的語言有 Gremlin, Cypher, GQL, SPARQL, PGQL, GraphQL ...,如果說 SQL 是處理關聯式資料庫的語言,那處理 Graph DB 就是上面列出來的這幾種。

舉例:

| Query Language | Statement | | -------------- | -------------------------- | | SQL | SELECT * FROM table_name | | Gremlin | g.V().hasLabel(label_name) |

在這個為期 2-3 週的研究,我們使用 Gremlin,可以在 AWS Neptune 上被支援,當初有想說用 Python,但不知道為什麼 Python 在我測試的 Jupyter Notebook 裡完全不 work,後來參考 AWS 的範例,決定使用 Gremlin。

來一點 Gremlin Cheat Sheet

%%Gremlin

// 列出所有的 Nodes
g.V()

// 列出限制幾筆 Nodes (25筆)
g.V().limit(25)

// 列出所有的Edges
g.E()

// 列出所有的 Nodes跟他的值
g.V().valueMap()

// 列出所有的 Nodes他本身的Id + 他的值
g.V().valueMap(true)

// 列出所有的 Edges跟他的值
g.E().valueMap(true)

// 刪除所有Nodes <-- 這麼危險的指令當然也要教你們辣
g.V().drop().iterate()

// 刪除所有的Edges
g.E().drop().iterate()

// 加一個 Node
g.V().add("Company")

// 加一個 Node 跟 Property
g.V().add("Company").property(id, "COM-0001").property("name", "Innova").as("COM-0001")
g.V().add("Employee").property(id, "EMP-0001").property("name", "Mina").as("EMP-0001")

// 加一個 Edge 跟 Property (填id)/然後addE是關係的名字: 連接 員工 -> 公司
g.V("EMP-0001").addE("belong").to(__.V("COM-0001")).property("checkIn", "2022-02-14")

// 連續加好多個資料: 尾巴都加 next(), 但最後一筆不要加
g.V().add("Company").property(id, "COM-0001").property("name", "Innova").as("COM-0001").next()
g.V().add("Company").property(id, "COM-0002").property("name", "Google").as("COM-0002").next()
g.V().add("Company").property(id, "COM-0003").property("name", "Tesla").as("COM-0003")

// 撈出同Label的資料,就是你看到上面是Company,會撈出 Innova (Node), Google(Node), Tesla(Node)
g.V().hasLabel("Company")

// 撈出指定id的 Node/Edge
g.V("COM-0001")
g.E("<id>")

大概就以上這些。

關聯式資料庫(RDB) VS 圖資料庫(Graph DB)

| | Graph DB | 關聯式資料庫(RDBMS) | | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------- | | 形式 | Nodes, Edges | Tables 有 Rows(幾筆資料) 和 Columns(欄位) | | 關係 | 會是使用 Edges 連結 Nodes | 關聯跨 Table,用 Foreign Keys 去關聯不同的 Table | | 複雜的查詢 | 搜尋的很快,不需要用 Joins 語法 | 需要使用 Joins 語法才能撈出在不同 Table 的資料 | | 使用案例 | 當需要一堆關聯跟關係時,像是社群網站或搜尋引擎。高連接度的場合,比方說家庭樹/族譜(族譜用在這應該很輕鬆) 資料的 Schema/欄位需求需要一直變動(畢竟不用先定義欄位名稱) | 存取很多或很複雜的資料, 比方說 Json,如果需要做複雜的運算,或者像 IoT 那樣大量的資料(應該是吧 xd?) | | 長相 | | | | 優點 | 如果有額外的屬性可以直接加,不用多新增一個欄位跟定義. 並非所有的資料都有相同的屬性,可以依據不同的資料加不同的屬性 (在關聯式資料庫,就算某筆資料沒有該屬性,但存在同個 Table,那筆資料就是要填空). 屬性沒有規定格式,想存數字就數字,想存文字就文字。 | 比較適合處理大量的資料,比起 GraphDB 需要用走訪(Tree 資料結構)一直去查找下一個節點,關聯式資料庫已經知道所有有多少筆資料了。 | | 缺點 | 需要特定的 Label 去撈同個類別的資料(Nodes). 對於你有特定的 id 想撈一筆資料,其實沒什麼意義。如果你需要在同一個屬性存取很長很複雜的內容,也許不太適合。 | 看起來是說關聯式資料庫對於深度分析,擁有的效能比較差(這邊大家有空再去查查缺點) |

實作 Part

解釋完抽象概念後,當然要來一點實作的部分才能理解,這個部分分成三個階段:

  • 開啟 Amazon Neptune 資料庫 + Jupyter Notebook
  • 用 Gremlin 語言做簡單的塞資料跟搜尋資料
  • 實現資料視覺化 (Data Visualization)

那麼就開始吧!

開啟 Amazon Neptune 資料庫 + Jupyter Notebook

我不確定大家要不要用 Amazon 的 Neptune 資料庫。

因為很貴

起初想說自己創了一個新帳號,用 Free Tier 免費方案應該不會扣到錢,但... 一開始免費方案的選項就選錯了,然後也不知道為什麼我選了免費方案的選項還是被扣,所以我總共就是兩個月被扣 1400,看起來還好?不是,那是我在 11 月底玩了一週被扣 700 塊,然後不知道為什麼在 12 月初換了一個選項創 Neptune 又被扣 700,真搶錢邪門,但反正...

我這一 Part 很兩光,會寫的很不負責任,你們自己評估看看吧 XD

進到可愛的 Amazon 頁面,直接在 Search Bar 上搜尋 Neptune。

請把左上邊三條線點開。

點選 Database,然後按右上方的 Create database。

好了這個部分要小心一點。

如果沒記錯的話,AWS Neptune 免費方案是 Provisioned + db.t3.medium

請確認你的地區,如果你怎麼創資料庫都Failed,去確認 CloudWatch 都報一個錯

那就是,你目前所在的地區(你可以看你右上方的地區),沒有支援 Neptune db.t3.medium 的選項。我可以創的地區是us-east-1

在 Create database 裡,Engine options,請選 ProvisionedServerless不是免費的

記住,Serverless 不是免費的。

Templates 麻煩選 Development and TestingDB instance size 請選 Buerstable classes: db.t3.medium

Connectivity這個部分比較麻煩,關乎到權限問題,如果你沒有權限,還是請你家的 MIS 或 DevOps 幫你創吧 XD,因為權限很麻煩。但如果你是 Root User,就開外掛吧,VPC沒有的話就創一個,其他不用管。

Notebook configuration,我們需要用 Jupyter Notebook 來跟 Neptune 這個資料庫連線處理資料,所以要勾選 Create notebook,IAM Role 有權限就直接創一個,其他好像都預設設定就可以了。

創完之後會看到資料庫正在創,然後去左邊的選單 Panel 點 Notebooks也會看到 Jupter Notebook 已經創好且連接於你創的資料庫了。

至於為什麼我這邊給的圖是 serverless? 因為,我的帳號被扣 1400,後來我就把資料庫刪了,公司提供一個測試帳號做研究,然後公司的後端權限大神幫我們把資料庫開好了,開 serverless 選項。

但還是要提醒大家我一開始用我自己的帳號開 serverless,不是免費的....,至於 Provisioned, 是官方文件上說的,期待勇者驗證讓我知道了。

記得沒有用服務時,要把資料庫跟 Notebook 都先 Stop 停止,才不會一直花到錢。

用 Gremlin 語言做簡單的塞資料跟搜尋資料

接下來打開你的 Notebook,我們用 Gremlin 簡單的塞幾筆資料。

首先可以使用指令來看看資料庫裡有什麼!

// 記得,在AWS的Jupyter Notebook 內要用這個語法先標示接下來是Gremlin語言
%%gremlin

// 列出所有 Nodes
g.V()

我的資料庫本來就有些之前輸入的資料,一般來說剛創好的資料庫會是空的,如果有報錯的話,可以檢查一下是不是忘記加 %%gremlin 或檢查是不是資料庫還沒創好或忘記 start 運行。

接下來我們來加一點資料,就加兩個人吧!

%%gremlin

g.addV("People").
     property(id,"PPL-0001").
     property("name","Amy").
     property("age",29).
     property("gender","F",).
     property("job","Engineer").
     as("PPL-0001").next()

g.addV("People").
     property(id,"PPL-0002").
     property("name","Jason").
     property("age", 31).
     property("gender","M",).
     property("job","Salesmen").
     as("PPL-0002")

我們加兩個 Node(兩個人),分別是屬 People 的 Label,Property 有 id, name, gender, job,一個人名字是 Amy,另外一個是 Jason。

在用g.V()列出所有 Node,便可以看到新增的兩個 Node,PPL-0001 跟 PPL-0002。

然後,如果想看到屬性,可以用

g.V().valueMap(true)

列出所有的 Node 跟他們的屬性資料。

然後,我們來使用 GraphDB 特有的功能 Edge,為這兩個人加一點關係

我想表示 Amy 喜歡 Jason 從 2022 年 8 月開始。

%%gremlin

// 給PPL-0001 Amy 加一個Edge like喜歡 指向 PPL-0002 Jason,
g.V('PPL-0001').addE('like').to(__.V('PPL-0002'))

可以看到 Edge 加進去囉!

所以現在在資料庫裡面我們有兩筆 Node 跟 1 筆 Edge

  • PPL-0001
  • PPL-0002
  • PPL-0001-like->PPL-0002

可是現在的資料都是以文字形式呈現,比較難理解,現在就來到了資料視覺化的部分了!

實現資料視覺化 (Data Visualization)

在我們的研究中,有研究三種方法是對於 Graph Database 的資料視覺化,其中有兩個工具是不需要真的安裝資料庫,所以如果你覺得害怕 Neptune 創立後,會花很多錢,但又想玩玩看 Graph Database 跟 Gremlin 語法,這邊會提供兩個工具。

總共是下面三個:

aws/graph-notebook

aws/graph-notebook 是一個 Python Package,然後可以用 Jupyter Notebook 使用,所以這次我們的研究實作部分的視覺化呈現,主要就是用這個 Package。沒意外的話,在 AWS 的 Notebook 創好後,已經內建在裡面。

有興趣的話可以去逛他的內容,不過我們這邊研究了一個指令可以將想要呈現的資料視覺化。

%%gremlin -p v,ine,outv,oute,inv
g.V().or(hasLabel("<Label1>"), hasLabel("<Label2>"))
     .inE().outV()
     .outE().inV().path().by(valueMap(true))

運用這個指令,然後在 or 這邊寫上所有你想要呈現的 Label 名稱,可以用圖形的方式呈現你的資料。

所以這是,我們剛剛輸入的三個資料,可以點 Node 或 Edge,然後再點右上方的三個線來看屬性。

如果想找關鍵字,可以使用右上方的 Search Bar,輸入你想找的字,會秀出包含關鍵字的 Node 或者 Edge,如圖。

視覺化的部分,我前面沒有輸入太多資料,所以沒怎麼能呈現,來曬一下我們這次研究自己模擬的一個場景,不會牽扯到公司機密。

用一樣的指令執行,可以看到撈出了很多先前創的資料,接著一樣點 Graph 的部分,就可以看到資料視覺化的呈現。

我承認當時 Edge 命名不好,所以看起來很亂哈哈。

一樣用 Search Bar 搜尋名字,該名字相關的 Node 會跳出。

以上就是用 aws/graph-notebook這個套件在 Jupyter Notebook 裡視覺化資料的過程。

G.V()

接下來介紹一下G.V()這個軟體,這個軟體是 AWS 提供Neptune 可連接的第三方軟體,其中一個軟體。

他是直接下載到電腦端的桌機軟體,無論是 Windows/Mac/Linux 版本都有。

這個軟體就很像 MySQL WorkBrach 的感覺,他允許你可以創一個 playground 玩耍天地,而不用創任何資料庫,你就可以只在電腦端用 Gremlin 語言玩 Graph Database,然後每個動作,無論是 show V 或者創 V/E,都會有一個按鈕可以看目前的資料視覺化成圖型,可以說是非常方便。

但後來我們停止了研究,有幾個原因。

  • 要能連接資料庫,要付費 Pro 版本,我們的研究計畫中沒有這個經費。我們本身就希望能夠研究用這個軟體連接 Neptune。
  • 我發現當 addE,加 Edge 後,之前輸入的所有 Node V 都會不見,這會增加我們除錯的天數,所以後來就先停止。我不確定是不是只發生在 Playground,我們當初是只有使用 Playground。

Gremlify

最後一個資料視覺化的工具是線上網站,不用安裝,目前知道是免費使用,我覺得是如果沒有創資料庫的打算,可以試試看這個線上網站來試玩。

叫做 Gremlify,這個網站我目前沒有實際使用,但之所以這麼推,是因為這個網站是另外一個組員找到的,而且在會議中他也有實際操作給我們看,實際看過後覺得是一個很方便很讚的網站。

沒有圖可以 show,但可允許你可以用滑鼠直接創立 Node 跟 Edge,光這點不用輸入指令,我想應該就蠻人性化的哈哈,方便許多。

更多的功能等大家去試玩,有心得再分享給我啦!

好啦,以上就是我們這次跨團隊 Innovative Idea Research 的研究筆記。除了跨團隊和其他團的組員合作很新奇之外,我也和我們團隊一直以來都沒合作過的組員一起合作,而且接觸的技術是一個全新 0 經驗的技術,真的是很棒的經驗,除了紀錄研究筆記外,也特別想把這個經驗給紀錄下來。

尤其在跨團隊合作時,得知該團隊的組員年後要離職,這會是第一次但也是最後一次的合作了,那我們更要趁這次機會好好的研究,好好的創造美好的回憶,好好的準備跟呈現完整我們的努力。