Neo4j匯入CSV與情境查詢-上

匯入 CSV 建立 Graph 並進行關聯查詢

即使 neo4j 可以利用它的套件 neo4j ETL Tool 進行連結資料庫,快速的建立 grpah database。但在某些狀況下可能不太方便,例如有些人可能不太會操作 RDBMS、或者想要手動建立一份簡單的模擬資料。那利用匯入 csv 的方式將會適合以上的狀況快速建立一個範本。

資料情境說明

在今年金管會推出的 理專十誡 2.0 中,有條態樣是關於理專與客戶之間的聯絡資訊控管。

理財專員所屬客戶與理財專員留有相同手機號碼、通訊地址、電子郵件信箱,且於一定期間之交易達一定金額或一定筆數者。

某些理專會再填寫客戶資料的時候,將聯絡資訊(電話、地址…等) 輸入自己的,這其實會造成在內控方面不確實。但有時候我們不希望找到事實上可能是因為理專的親屬關係會填入自己聯絡資訊的狀況。

這次採用的資料,是由個人資料所組成,其中最為重要的是 關係人 ,我們希望透過尋找關係人與個人資料之間的關聯與否。

Neo4j

*以上資料姓名隨意發想及北市高中地址、電話,如有雷同純屬巧合。

匯入 CSV

當你有一份 csv 的時候,我們必須將這份 csv 丟進 neo4j 本地的資料夾裡面,讓他去進行讀取。通常這個資料夾並不好找,因此我們藉由程式的介面去進行開啟。

  1. 將點擊該 Project 的 DBMS
  2. 點擊 Open folder
  3. 點擊 Import

以上步驟完成就會開啟一個資料夾,這時你只要將 csv 複製進去即可。

從示意圖可以看到,其實它是以 DBMS 為一個單位去做管理,也就是如果你某個 Project 底下有很多 DBMS,那它們的 import 資料夾其實是各自獨立的。

Neo4j

如果你是硬派男子漢,想要直接透過路徑去打開資料夾的話...以下方法提供給你參考

使用 Cypher 建立節點關聯

當 csv 複製到資料夾後,並不代表一切都解決了,我們還需要透過 Cypher 來進行匯入以及建立節點與關聯。

我們先執行以下這段語法,再來看看結果如何,後續會有更詳細的解說。

//匯入 csv 
LOAD CSV WITH HEADERS FROM "file:///cu11.csv" AS line

//建立節點 (包含設立 property)
MERGE (name:姓名 {姓名: line.contactName,關係人: line.relationship_1,職稱:line.contactTitle,城市:line.city,國家:line.country})
MERGE (address:地址 {地址:line.address})
MERGE (phone:電話 {電話:line.phone})

//建立關聯
MERGE (name)-[:have_address]->(address)
MERGE (name)-[:have_phones]->(phone)

//依情境建立關聯
WITH name
MATCH (searched:姓名),(matched:姓名)
WHERE searched.姓名 = matched.關係人
MERGE (searched)-[r:relation]->(matched)

錯誤建立關聯的 graph 語法

我們直接執行完來看結果。這張 graph 看似完美,但其實有一些問題,不知道眼尖的你有無發現?

Neo4j

錯誤的關聯結果

沒錯…有些人的 關係人 並沒有出現!

像是 翁富邦 黃都城 他們之間其實還有一層與 王偉康 的關聯 或者是 曾柏彥 他的關係人 曾柏偉 也沒有顯示。

這樣會造成後續在做情境查詢的時候出現不正確的結果。

Neo4j

貼心的再給你看一次原始資料

該如何建立出正確的關聯?

上述的語法建立的節點只會有 contactName 的這個列表裡的名單,relationship_1 的名單就不會出現在節點裡面,因此我們需要多考量到這 2 個 columns 裡的名單應都要建立節點,在後續的建立關聯才不會遇到以上的問題。

首先我們先對 DB 設下節點的限制,我們針對 姓名 這個節點及其的 姓名 屬性進行限制為 unique。如此一來在後續的對 contactName、 relationship_1 這 2 個 columns 裡的名單建立節點,才不會出現重複建立的狀況。

//對 DB 設下限制
CREATE CONSTRAINT ON (c:姓名) ASSERT c.姓名 IS UNIQUE;

如果你不想要這個限制,那將 CREAT 改成 DROP ,在這個 DB 就不會有這個限制了。

//對 DB 刪除限制
DROP CONSTRAINT ON (c:姓名) ASSERT c.姓名 IS UNIQUE;

接下來就是建立節點與關聯了。

  1. 匯入 csv *注意有些語法,會沒有寫 WITH HEADERS,會造成後續無法由表頭讀入資料。


  2. 建立節點 (包含設立 property 屬性) 這裡一共創建了三個 label : 姓名電話地址,對 姓名 除了自己本身的又額外增加了關係人職稱 的屬性。 但你可以看到我們除了 name 多創了一個 name1 的 label,這裡就會的對每筆資料的 relationship_1 進行創建,當然前述所建立的限制就會有下圖的比對作用。
Neo4j
  1. 建立基本關聯 對所有的 姓名 進行了 地址、 電話 的關聯

    *在第 3 點的 地址、 電話的關聯,其實也可以利用 Property (屬性) 的方式進行建立,但在本次範例希望能給入門者視覺化的呈現他們對於每個人其中的關聯。

  2. 依情境建立關聯 這裡的情境指的是 姓名 這個 label 的所有 node 裡的 姓名關係人 屬性 相互去做比對、關聯。
Neo4j

情境關聯示意圖

//匯入 csv 
LOAD CSV WITH HEADERS FROM "file:///cu11.csv" AS line

//建立節點 (包含設立 property)
MERGE (name:姓名 {姓名: line.contactName,關係人: line.relationship_1,職稱:line.contactTitle,城市:line.city,國家:line.country})
MERGE (name1:姓名 {姓名: line.relationship_1})
MERGE (address:地址 {地址:line.address})
MERGE (phone:電話 {電話:line.phone})

//建立基本關聯
MERGE (name)-[:have_address]->(address)
MERGE (name)-[:have_phones]->(phone)

//依情境建立關聯
WITH name
MATCH (searched:姓名),(matched:姓名)
WHERE searched.姓名 = matched.關係人
MERGE (searched)-[r:relation]->(matched)

正確建立關聯的 graph 語法

補充說明: 大量匯入 csv

如果你的 csv 檔案非常的大、筆數多,直接使用 LOAD CSV 在匯入的時有可能因為記憶體等其他因素有機會出現錯誤,造成整份 csv 都寫入失敗。建議在匯入前輸入 :auto USING PERIODIC COMMIT 或者是 USING PERIODIC COMMIT,將 :auto 前綴刪除。此語法會批量的匯入你的 csv ,在預設的語法(未加數字)是 1000 筆的批量寫入,當然你也可以在最後面加上數字進行修改。以下範例是每 500 筆進行寫入。

//:auto USING PERIODIC COMMIT 
:auto USING PERIODIC COMMIT 500

圖/文:Rod

專人協助

由偉康業務人員為您詳細說明偉康的解決方案,以及相關產業經驗。

立即訂閱電子報

掌握最新科技趨勢!