logo
Loading...

4. 圖資料庫 Neo4j 與 Cypher 語言基礎訓練 - 知識圖譜與 GraphRAG - Cupoy

模組 1:圖資料庫與 Neo4j 基礎 1. 教學目標 了解圖資料庫的核心概念與應用場景。 認識 Neo4j 的基本組成與運作模式。 能夠在本機或雲端環境安裝並啟動 Neo4j。 了解 Neo...

模組 1:圖資料庫與 Neo4j 基礎 1. 教學目標 了解圖資料庫的核心概念與應用場景。 認識 Neo4j 的基本組成與運作模式。 能夠在本機或雲端環境安裝並啟動 Neo4j。 了解 Neo4j 提供的工具(Neo4j Browser、Neo4j Bloom)並能簡單操作。 2. 圖資料庫 vs 關聯式資料庫 關聯式資料庫 (RDBMS) 圖資料庫 (Graph DB) 結構 表 (Table)、行 (Row) 節點 (Node)、關係 (Relationship) 主從關係 透過外鍵關聯 直接使用關係 (edges) 查詢語言 SQL Cypher (Neo4j) 擴充性 擴充通常較困難 天生可以水平擴充 (Scale-out) 適用場景 交易型系統、列舉型查詢 圖形關係分析、路徑搜尋、推薦系統等 3. Neo4j 的架構與核心概念 3.1 Neo4j 架構 圖引擎:Neo4j 以高效的圖資料結構儲存資料,可快速進行關係查詢。 存儲層:使用原生圖儲存方式。 查詢層:使用 Cypher 語言進行查詢和操作。 3.2 Neo4j 核心元素 節點 (Node) 圖中的「實體」(例如:人、產品、城市)。 可以包含多個「屬性 (Properties)」。 關係 (Relationship) 節點與節點之間的連結 (例如:朋友關係、購買行為)。 也可以包含「屬性」。 標籤 (Label) 用於將節點分類。 例如:Person、Movie、Company。 關係類型 (Relationship Type) 表示關係的種類。 例如:FRIEND_OF、WORKS_AT、ACTED_IN。 索引 (Index) 與 約束 (Constraint) 用於加速查詢或保證資料一致性。 常見的索引範例:基於節點屬性的索引,如 CREATE INDEX FOR (n:Person) ON (n.name) 4. 安裝與環境設定 4.1 本地安裝(Neo4j Desktop 或 Community Edition) 下載 Neo4j Desktop 前往 Neo4j 官方網站 下載對應作業系統版本。 安裝完成後啟動 Neo4j Desktop。 建立並啟動資料庫 在 Neo4j Desktop 中,新增一個 Project。 新增一個 Local Database,設定好密碼後啟動。 連線到資料庫 使用 Neo4j Browser 或 Neo4j Desktop 內建的瀏覽器連線到 bolt://localhost:7687。 使用安裝時設定的帳號密碼登入。 4.2 雲端部署(Neo4j Aura) 前往 Neo4j Aura 註冊或登入帳號。 建立一個 Neo4j Aura DB,系統會自動產生連線資訊。 使用 Neo4j Browser 或其他工具連線到此雲端資料庫。 4.3. 雲端沙盒版本 5. 使用 Neo4j Browser 與 Neo4j Bloom 5.1 Neo4j Browser 進入方式:若在本機安裝,可透過 http://localhost:7474/ 進入;或是在 Neo4j Desktop 內部的瀏覽器。 功能重點: 輸入 Cypher 查詢指令。 查看圖形化結果或表格式結果。 可以使用 :help 指令查看教學與常見命令。 5.2 Neo4j Bloom 可視化探索工具:支援更直覺的「節點-關係」拖曳與操作。 使用場景: 資料探索:透過關鍵字或篩選器快速找到想要的資料。 可視化報告:將複雜關係以圖型的方式展示。 6. 初步操作示例 查看現在資料庫內所有的節點與關係 MATCH (n) RETURN n LIMIT 25 由於目前可能沒有資料,結果會是空的或僅有系統內建的節點。 創建一個節點 CREATE (p:Person { name: "Alice", age: 25 }) RETURN p 建立一個標籤為 Person,屬性包含 name 和 age 的節點。 檢查剛剛創建的節點 MATCH (p:Person) WHERE p.name = "Alice" RETURN p 若看到節點圖示或表格即可確定資料成功寫入。 刪除一個節點(僅示範用) MATCH (p:Person { name: "Alice" }) DELETE p 若要刪除的節點有關係,需使用 DETACH DELETE 一併刪除所有關係。 7. 實作練習 練習 1:安裝 Neo4j 請學員選擇最適合自己的環境(本機安裝或 Docker)。 啟動 Neo4j 並進入 Neo4j Browser,確認可以輸入查詢。 練習 2:創建基本節點與關係 在 Neo4j Browser 中,創建兩個節點: (p1:Person { name: "Alice", age: 25 }) (p2:Person { name: "Bob", age: 27 }) 為 Alice 與 Bob 之間建立一個關係: CREATE (p1)-[:FRIEND_OF]->(p2) 查詢並顯示這些節點與關係: MATCH (n) RETURN n; 驗證關係是否正確。 練習 3:使用 Neo4j Bloom(若環境允許) 進入 Neo4j Bloom。 找到先前創建的 Person 節點並標記顏色或做分組。 觀察節點與關係的可視化結果。 9. 小結 圖資料庫的基本概念:節點、關係、屬性是理解後續課程的關鍵。 Neo4j 的安裝:可選擇本機、雲端或 Docker,視需求與環境而定。 Neo4j Browser 與 Bloom:提供直觀的查詢介面與圖形化視圖。 在完成本模組後,你已經能夠: 了解為什麼要用圖資料庫,以及與傳統 RDBMS 的差異。 在自己的電腦或雲端啟動並連線 Neo4j。 透過 Neo4j Browser 或 Bloom 進行基礎的圖操作與視覺化。 參考連結 Neo4j 官方文件 Neo4j Desktop 下載 Docker Hub - Neo4j Neo4j Aura 雲端服務 模組 2:Cypher 基礎查詢 1. 教學目標 學會使用 Cypher 的基本查詢語法(MATCH, RETURN, WHERE)。 理解並能執行新增、修改、刪除圖資料的常用指令(CREATE, MERGE, SET, DELETE 等)。 能在 Neo4j 環境中使用 Cypher 建立基礎的圖模型(節點、關係)。 了解如何使用條件過濾與簡單的聚合函數來處理資料。 2. Cypher 語言概觀 Cypher 是 Neo4j 提供的宣告式圖形查詢語言,用來針對節點(Node)與關係(Relationship)進行: 查詢:透過模式匹配(pattern matching)篩選出想要的資料。 建立 / 更新 / 刪除:對圖資料庫做增刪改。 2.1 為什麼使用 Cypher? 類似 SQL 的結構,容易上手:MATCH 類似 SQL 的 SELECT。 專門為圖關係設計,可快速表達「節點–關係–節點」的匹配邏輯。 高可讀性,對新手較為友善。 3. 基本查詢語法 3.1 MATCH 與 RETURN MATCH:用來描述要在圖中「尋找」何種節點或關係。 RETURN:用來指定要輸出的結果。 範例 MATCH (p:Person) RETURN p 語意:在圖中尋找所有標籤為 Person 的節點,將其回傳。 可能的顯示:在 Neo4j Browser 中看到多個人形節點。 3.2 WHERE 條件過濾 透過 WHERE 可指定屬性、關係等條件來過濾結果。 範例 MATCH (p:Person) WHERE p.age > 25 RETURN p.name, p.age 語意:尋找所有 Person 並篩選出 age > 25 的節點,只回傳名字與年齡。 4. 建立與修改資料 4.1 CREATE 用於建立節點或關係,若資料庫中尚無符合的節點 / 關係,便會新建。 創建節點 CREATE (p:Person { name: "Alice", age: 25 }) RETURN p 創建關係 MATCH (a:Person { name: "Alice" }), (b:Person { name: "Bob" }) CREATE (a)-[:FRIEND_OF]->(b) RETURN a, b 語意:先找到名為 Alice 與 Bob 的節點,然後在兩者之間建立一條 FRIEND_OF 關係。 4.2 MERGE 用於「如果不存在就創建,如果存在就使用」的模式匹配。 避免重複建立相同節點或關係的好工具。 範例 MERGE (p:Person { name: "Charlie" }) RETURN p 若圖中尚未有標籤為 Person、name = "Charlie" 的節點,會自動建立;否則,會直接匹配到現有節點。 4.3 SET 用於設定 / 更新節點或關係的屬性。 範例 MATCH (p:Person { name: "Alice" }) SET p.age = 26, p.city = "Taipei" RETURN p 更新 Alice 的 age 屬性、新增 city 屬性。 4.4 REMOVE 移除節點的標籤或屬性。 範例 MATCH (p:Person { name: "Alice" }) REMOVE p.city // 移除屬性 REMOVE p:Person // 移除標籤 RETURN p 5. 刪除與變更資料 5.1 DELETE 用於刪除節點或關係。 若直接刪除節點,但該節點還有關係存在,Cypher 會報錯。 範例 MATCH (p:Person { name: "Alice" })-[r:FRIEND_OF]->(b) DELETE r 只刪除 Alice 與 Bob 之間的 FRIEND_OF 關係。 5.2 DETACH DELETE 當要連同節點與該節點的所有關係一起刪除時,使用 DETACH DELETE。 範例 MATCH (p:Person { name: "Alice" }) DETACH DELETE p 會刪除 Alice 以及其所有關係。 6. 實作示例與練習 6.1 示例:建立簡易社群圖 步驟 1:建立節點 CREATE (alice:Person { name: "Alice", age: 25 }) CREATE (bob:Person { name: "Bob", age: 27 }) CREATE (charlie:Person { name: "Charlie", age: 30 }) RETURN alice, bob, charlie 步驟 2:建立關係 MATCH (alice:Person { name: "Alice" }), (bob:Person { name: "Bob" }), (charlie:Person { name: "Charlie" }) CREATE (alice)-[:FRIEND_OF]->(bob), (bob)-[:FRIEND_OF]->(charlie), (alice)-[:FRIEND_OF]->(charlie) RETURN alice, bob, charlie 步驟 3:查詢並顯示關係 MATCH (p:Person)-[r:FRIEND_OF]-(q:Person) RETURN p, r, q 檢查社群關係是否正確。 6.2 練習 1:資料新增與修改 新增一個節點,標籤為 Movie,並指定屬性 title 為 "The Matrix",year 為 1999。 更新該節點的屬性 year 為 1999 改為 2000。 將節點的標籤由 Movie 改為 Film(先 REMOVE,再 SET)。 6.3 練習 2:條件篩選 查詢所有 Person,挑選出 age > 26 的名單。 回傳名單裡每個人的 name 與 age。 篩選結果後,若有需要,將符合條件的人加上標籤 Senior。 6.4 練習 3:刪除操作 嘗試使用 DELETE 刪除某個有關係的節點,觀察系統回應(預期會出錯)。 使用 DETACH DELETE 成功刪除該節點與相關關係。 驗證是否刪除成功。 7. 常見問題與注意事項 CREATE vs MERGE CREATE:每次執行都會產生全新的節點或關係。 MERGE:若已存在符合條件的節點或關係,則不重複建立。 大小寫敏感度 參考預設:屬性名稱區分大小寫,而標籤與關係類型也區分大小寫。 查詢效能 剛開始資料量不大時不明顯,但實務上會使用索引(CREATE INDEX)優化查詢。 刪除資料 請小心操作 DETACH DELETE,因為會連帶刪除所有關係,無法復原。 8. 小結 本模組介紹了 Cypher 的基本查詢、資料建立與刪除等語法。 透過 MATCH ... RETURN ...,我們可以很直觀地取得節點及關係;使用 CREATE、MERGE、SET、DELETE 等指令,能對圖中的資料進行靈活操作。 重點:理解 MATCH 與 MERGE 的差異、學會使用 WHERE 做條件篩選,以及掌握基本的增刪改查工作流程。 參考連結 Neo4j Official Cypher Manual Neo4j Developer Guides Cypher Refcard (官方速查表) 模組 3:進階 Cypher 操作 1. 教學目標 熟悉進階模式匹配技巧(OPTIONAL MATCH, WITH, UNWIND 等)。 了解常用聚合函數(COUNT(), AVG(), SUM(), COLLECT())並應用於統計分析。 學會使用索引與檢查查詢計劃(EXPLAIN, PROFILE)來優化查詢效能。 能運用複雜查詢模式(FOREACH, CASE)以及批量寫入方法(CALL apoc.periodic.iterate)。 2. 進階模式匹配與變數 2.1 OPTIONAL MATCH 用途:在查詢關係/節點時,若相關資料不存在,也不會中斷整個查詢,而是返回 null 值。 適用情境:查詢某個使用者的「選擇性」關係,如使用者可能沒有朋友、或沒有指定某屬性時。 範例 // 若 p 沒有繼續關係存在,不會報錯,只是回傳 null MATCH (p:Person) OPTIONAL MATCH (p)-[r:FRIEND_OF]->(q:Person) RETURN p.name AS person, q.name AS friend 若 p 沒有朋友,就會看到 friend 欄位是 null。 2.2 WITH 管道操作 功能:將前一次查詢的結果傳遞給下一個查詢,可用來分段處理、聚合後再進行操作。 避免變數衝突:在大型查詢中,使用 WITH 能將階段性結果命名後再使用。 範例 MATCH (p:Person)-[:FRIEND_OF]->(q:Person) WITH p, COUNT(q) AS friendCount WHERE friendCount > 2 RETURN p.name AS person, friendCount 第一步:找到所有 Person 與朋友之間的關係,計算朋友數。 第二步:只篩選朋友數大於 2 的人並回傳。 2.3 UNWIND 功能:將列表 (List) 的資料「展開」成多筆獨立的記錄,常用於批量寫入或處理陣列資料。 範例 WITH ["Alice", "Bob", "Charlie"] AS names UNWIND names AS name CREATE (p:Person { name: name }) RETURN p 將 names 列表中的 3 個名稱逐一展開並各自建立節點。 3. 聚合函數與資料統計 3.1 常用聚合函數 COUNT():計算資料筆數 SUM():對某屬性數值做加總 AVG():對某屬性數值做平均 COLLECT():將多筆記錄彙整成列表 範例:計算每個人朋友數 MATCH (p:Person)-[:FRIEND_OF]->(q:Person) RETURN p.name AS person, COUNT(q) AS numFriends ORDER BY numFriends DESC 依照朋友數做降冪排序。 3.2 組合使用 COLLECT() MATCH (m:Movie)<-[:ACTED_IN]-(actor:Person) RETURN m.title AS movie, COLLECT(actor.name) AS actors 回傳每部電影的演員清單,COLLECT() 產生一個列表。 4. 索引與效能優化 4.1 索引 (Index) 目的:加速查詢。例如,當我們常以 name 屬性搜尋 Person 節點時,可對 name 建立索引。 範例:CREATE INDEX person_name_index FOR (p:Person) ON (p.name) Neo4j 4.x/5.x 之後的語法會有不同版本,也可能支援 CREATE TEXT INDEX、CREATE RANGE INDEX 等。 4.2 檢查查詢計劃:EXPLAIN 與 PROFILE **EXPLAIN**:不會執行查詢,但顯示執行計劃。 **PROFILE**:執行查詢並顯示實際執行計劃與運行統計。 範例 EXPLAIN MATCH (p:Person) WHERE p.name = "Alice" RETURN p 查看是否有使用索引或做了全圖掃描 (NodeByLabelScan)。 5. 複雜查詢技巧 5.1 FOREACH 處理批量更新 適用於需要對已經「匹配」到的結果做批次操作時。 範例 MATCH (p:Person { city: "Taipei" }) WITH COLLECT(p) AS persons FOREACH (onePerson IN persons | SET onePerson.city = "Taipei City" ) 將所有在 Taipei 的人更新為 Taipei City。 5.2 CASE 條件判斷 用於查詢結果中的邏輯判斷,類似 SQL 中的 CASE WHEN THEN ELSE END。 範例 MATCH (p:Person) RETURN p.name AS name, CASE WHEN p.age >= 18 THEN "Adult" ELSE "Minor" END AS ageGroup 5.3 交易與批量寫入:CALL apoc.periodic.iterate APOC(Awesome Procedures on Cypher)為 Neo4j 的常用外掛庫,提供許多實用工具。 apoc.periodic.iterate:在大量資料操作時,能分批處理以避免單次交易量過大。 範例 CALL apoc.periodic.iterate( "MATCH (p:Person) RETURN p", "SET p.active = true", {batchSize:1000, parallel:true} ) 分批(每次 1000 筆)對所有 Person 設定 active = true。 6. 實作示例與練習 6.1 練習:計算社群中每個使用者的朋友數並篩選 建立或使用既有的社群圖,例如 Person 與 FRIEND_OF 關係。 撰寫查詢,使用 MATCH 與 COUNT() 計算每個使用者的朋友數。 篩選出朋友數大於 2 的使用者,並使用 WITH 配合條件過濾。 回傳符合條件者的名字與朋友列表(可用 COLLECT())。 6.2 練習:建立索引並測試效能 建立一個索引: CREATE INDEX person_name_index FOR (p:Person) ON (p.name) 使用 PROFILE 對比索引前後查詢時間: PROFILE MATCH (p:Person) WHERE p.name = "Alice" RETURN p 觀察執行計劃中是否顯示使用索引掃描。 6.3 練習:使用 FOREACH 或 UNWIND 進行批量更新 準備一個名稱列表,批量建立節點或更新節點屬性。 使用 OPTIONAL MATCH 來處理資料不完整或關係不存在的狀況。 7. 常見問題與注意事項 OPTIONAL MATCH 陷阱 使用 OPTIONAL MATCH 後,若沒有匹配到資料,返回的資料欄位會是 null;後續操作需考慮 null 處理邏輯。 WITH 的資料範圍 WITH 會分隔查詢階段,只有在 WITH 之後被明確帶過去的變數,才能在下一階段使用。 大批量更新 建議善用 FOREACH、UNWIND 或 apoc.periodic.iterate 分批執行,避免單次交易過大導致記憶體不足或超時。 索引與節點數量 建立索引雖能優化查詢,但也會佔用空間並增加寫入成本,需權衡建立哪些索引最有效。 8. 小結 在本模組,你學習了: 進階模式匹配(OPTIONAL MATCH, WITH, UNWIND)的原理與用途。 聚合函數(COUNT(), AVG(), SUM(), COLLECT())應用於圖形資料的統計分析。 效能優化:如何使用索引、EXPLAIN 與 PROFILE 分析查詢計劃。 複雜查詢:FOREACH, CASE 以及大量更新的 apoc.periodic.iterate。 參考連結 Neo4j Cypher Manual - Advanced Queries APOC Library (Awesome Procedures on Cypher) Neo4j Performance Tuning 模組 4:圖分析與推薦系統 1. 教學目標 了解常見的圖演算法(最短路徑、PageRank、社群偵測等)及其應用場景。 學習使用 Neo4j 提供的 Graph Data Science (GDS) Library 或其他工具來執行圖分析。 能夠利用圖演算法成果,設計與實作簡易的推薦功能(朋友推薦、產品推薦等)。 掌握常見的推薦系統概念與在 Neo4j 中的實際落地方法。 2. 常見圖演算法與應用 2.1 最短路徑 (Shortest Path) 意義:計算兩個節點之間路徑的最小成本(可依權重或邊數計算)。 用途: 尋找社群中兩個人最短的「關係距離」。 地理/物流路徑最佳化。 Cypher 基本示例(僅適用於簡單最短路徑):MATCH (start:Person {name: "Alice"}), (end:Person {name: "Bob"}), p = shortestPath((start)-[:FRIEND_OF*]-(end)) RETURN p [:FRIEND_OF*] 表示可以走零到多段 FRIEND_OF 關係。 shortestPath() 只能處理無權重的路徑。若需要權重計算,建議使用 GDS 函式。 2.2 PageRank 原理:源於網頁排名演算法,衡量每個節點的「重要性」或「影響力」。 用途: 社群網路:找出「最具影響力」的使用者。 研究引用關係:找出「最具影響力」的文獻。 GDS Library 示例(假設已安裝 GDS 外掛):CALL gds.pageRank.write({ nodeProjection: 'Person', relationshipProjection: 'FRIEND_OF', writeProperty: 'pagerank' }) 為每個 Person 寫入屬性 pagerank,用以表示該節點的影響力分數。 2.3 社群偵測 (Community Detection) 目標:根據節點與關係的結構,將節點分成不同的社群。 常見演算法:Louvain、Label Propagation 等。 用途: 社群網路分群:找出興趣相近或互動頻繁的使用者群組。 推薦與行銷:對同一社群的用戶推送類似商品或內容。 GDS Library 示例(使用 Louvain):CALL gds.louvain.write({ nodeProjection: 'Person', relationshipProjection: 'FRIEND_OF', writeProperty: 'community' }) 為每個 Person 寫入屬性 community,表示該人所屬的社群。 2.4 連通成分分析 (Connected Components) 意義:找出圖中哪些節點彼此相連,屬於同一「連通子圖」。 用途: 檢查圖是否有互不連通的區塊。 針對大型網路,做區塊分割與獨立分析。 GDS Library 示例:CALL gds.wcc.write({ nodeProjection: 'Person', relationshipProjection: 'FRIEND_OF', writeProperty: 'componentId' }) 為每個人寫入 componentId,標示其屬於哪個連通子圖。 3. 推薦系統在 Neo4j 的應用 3.1 推薦系統基礎概念 過濾方式 **協同過濾 (Collaborative Filtering)**:根據相似用戶的行為做推薦。 **內容過濾 (Content-based)**:根據產品或內容本身的屬性(標籤、類別)做推薦。 **混合過濾 (Hybrid)**:結合協同過濾與內容過濾。 在圖資料庫中的優勢 自然地表達用戶與物品(或內容)之間的關係,並輕鬆延伸至社群關係。 快速查詢「朋友喜歡哪些商品」、「相似用戶還喜歡哪些內容」。 3.2 朋友推薦 (Friend Recommendation) 邏輯: 透過「朋友的朋友」(Friend-of-Friend) 進行推薦; 若許多共同朋友,則推薦可能性更大。 Cypher 範例:MATCH (me:Person {name: "Alice"})-[:FRIEND_OF]->(friend:Person)-[:FRIEND_OF]->(fof:Person) WHERE fof <> me // 排除自己 RETURN fof.name AS recommendedFriend, COUNT(*) AS mutualFriends ORDER BY mutualFriends DESC 簡單依「共同好友數量」決定推薦度。 3.3 物品推薦 (Item Recommendation) 邏輯: 若多人 (User) 同時喜歡 (LIKES) 相同產品 (Item),這些人之間可視為相似度較高; 可找到與自己相似的人所喜愛的其它產品,進行推薦。 Cypher 示例:MATCH (me:Person {name: "Alice"})-[:LIKES]->(item:Item)<-[:LIKES]-(other:Person)-[:LIKES]->(otherItem:Item) WHERE NOT (me)-[:LIKES]->(otherItem) RETURN otherItem.name AS recommendedItem, COUNT(other) AS similarityScore ORDER BY similarityScore DESC 依「多少人同時喜歡該產品」作為相似度分數。 4. 實作範例:社群推薦場景 以下是一個綜合示例,透過社群網路 + 共同喜好來推薦朋友或電影。 4.1 準備數據 建立一些使用者 (Person) 節點、電影 (Movie) 節點,以及「觀看 / 評分」等關係: CREATE (a:Person {name: "Alice"}), (b:Person {name: "Bob"}), (c:Person {name: "Charlie"}), (m1:Movie {title: "Inception"}), (m2:Movie {title: "Interstellar"}); // 建立朋友關係 CREATE (a)-[:FRIEND_OF]->(b), (b)-[:FRIEND_OF]->(c); // 建立喜好或觀看關係 CREATE (a)-[:LIKES {rating: 5}]->(m1), (a)-[:LIKES {rating: 4}]->(m2), (b)-[:LIKES {rating: 4}]->(m1), (c)-[:LIKES {rating: 3}]->(m1); 檢查資料是否成功建立: MATCH (n) RETURN n LIMIT 25 在 Neo4j Browser 檢視圖形。 4.2 試用 PageRank / 社群分析 PageRank(針對朋友關係): CALL gds.pageRank.write({ nodeProjection: 'Person', relationshipProjection: 'FRIEND_OF', writeProperty: 'pagerank' }) 完成後可透過以下查詢查看 Pagerank:MATCH (p:Person) RETURN p.name, p.pagerank ORDER BY p.pagerank DESC 社群偵測(Louvain): CALL gds.louvain.write({ nodeProjection: 'Person', relationshipProjection: 'FRIEND_OF', writeProperty: 'community' }) 檢視結果:MATCH (p:Person) RETURN p.name, p.community 4.3 朋友推薦與電影推薦示例 朋友推薦: MATCH (me:Person {name: "Alice"})-[:FRIEND_OF]->(friend:Person)-[:FRIEND_OF]->(fof:Person) WHERE fof <> me RETURN fof.name AS recommendedFriend, COUNT(friend) AS mutualFriends ORDER BY mutualFriends DESC 電影推薦(若 Alice 尚未看過的電影): MATCH (me:Person {name: "Alice"})-[:LIKES]->(commonMovie:Movie)<-[:LIKES]-(other:Person)-[:LIKES]->(newMovie:Movie) WHERE NOT (me)-[:LIKES]->(newMovie) RETURN newMovie.title AS recommendedMovie, COUNT(DISTINCT other) AS similarityScore ORDER BY similarityScore DESC 5. 常見問題與注意事項 GDS Library 安裝 需確保安裝對應版本的 Graph Data Science Plugin,並與 Neo4j 主版本相容。 大資料量的效能 圖演算法對記憶體與計算資源要求較高,需考量叢集方案或進行分批分析。 演算法參數調整 PageRank 的阻尼係數 (damping factor)、Louvain 的最低社群門檻等參數可能需要調校,才能得出較佳結果。 資料清理與前處理 需先確保節點與關係定義明確、屬性格式正確,避免演算法執行時產生大量錯誤或失真。 6. 小結 在本模組,你將學到: 圖分析:最短路徑、PageRank、社群偵測等演算法,並理解其核心概念與應用範圍。 Neo4j GDS:透過 Graph Data Science Library 快速執行圖演算法並將結果寫入節點屬性。 推薦系統:如何利用圖結構關係(例如:共同朋友、共同喜好)實作好友推薦或產品推薦。 實戰演練:整合圖分析、推薦邏輯,體會圖資料庫在社群分析與推薦場景的優勢。 參考連結 Neo4j Graph Data Science Library Neo4j Documentation - GDS Algorithms Neo4j Recommendation Use Cases Collaborative Filtering in Neo4j Blog 模組 5:Neo4j 與外部系統整合 1. 教學目標 學習如何使用程式語言(Python、Node.js 等)連接 Neo4j 並進行 CRUD 操作。 了解如何整合資料分析工具(如 Pandas)進行資料匯入或匯出。 掌握 Neo4j 與 Web Framework(Flask、Django、Express 等)組合,開發 RESTful API 或後端服務。 瞭解 Neo4j 在 RAG(Retrieval-Augmented Generation)應用中的角色與常見整合模式(GraphRAG)。 2. Neo4j 驅動與程式語言整合 2.1 官方驅動 (Official Drivers) Neo4j 提供多種官方驅動程式,如 Java、Python、JavaScript、**.NET、Go** 等,可直接透過程式碼與 Neo4j 通訊。 連線方式:透過 bolt:// 或 neo4j:// 協定進行連接。 認證與安全:提供基本的帳密驗證,也能設定 TLS/SSL 加密連線。 Python 範例 (neo4j 驅動) from neo4j import GraphDatabase uri = "bolt://localhost:7687" driver = GraphDatabase.driver(uri, auth=("neo4j", "password")) def create_person(tx, name): tx.run("CREATE (p:Person {name: $name})", name=name) with driver.session() as session: session.write_transaction(create_person, "Alice") driver.close() 重點:先建立 GraphDatabase.driver,再用 session 執行寫入或讀取交易 (write_transaction / read_transaction)。 2.2 第三方套件 (Python - py2neo) py2neo 是一個友善的 Python 庫,提供更高階的 API 進行操作。 範例: from py2neo import Graph, Node, Relationship graph = Graph("bolt://localhost:7687", auth=("neo4j", "password")) alice = Node("Person", name="Alice") bob = Node("Person", name="Bob") rel = Relationship(alice, "FRIEND_OF", bob) graph.create(alice | bob | rel) 3. 與資料分析工具整合 3.1 Pandas DataFrame 轉換 常見場景: 匯入 CSV / Excel 資料到 Neo4j 匯出 Neo4j 查詢結果到 DataFrame 做進一步分析 Python 範例:將查詢結果轉為 DataFrame import pandas as pd from neo4j import GraphDatabase uri = "bolt://localhost:7687" driver = GraphDatabase.driver(uri, auth=("neo4j", "password")) cypher_query = """ MATCH (p:Person) RETURN p.name AS name, p.age AS age """ with driver.session() as session: result = session.run(cypher_query) records = list(result) df = pd.DataFrame([r.data() for r in records]) print(df) driver.close() 重點:先執行 Cypher,取得 result,再將其轉為 DataFrame。 3.2 匯入 CSV 資料到 Neo4j 方法 1:利用 Neo4j 提供的 LOAD CSV 語句 LOAD CSV WITH HEADERS FROM "file:///people.csv" AS row CREATE (:Person {name: row.name, age: toInteger(row.age)}) 方法 2:透過程式語言讀取 CSV,再使用程式迴圈 CREATE 或 MERGE 節點。 4. 與 Web Framework 整合 4.1 Python - Flask 範例 安裝套件:pip install flask neo4j 建立簡易 API: from flask import Flask, request, jsonify from neo4j import GraphDatabase app = Flask(__name__) driver = GraphDatabase.driver("bolt://localhost:7687", auth=("neo4j", "password")) @app.route('/persons', methods=['GET']) def get_persons(): cypher_query = "MATCH (p:Person) RETURN p.name AS name, p.age AS age" with driver.session() as session: results = session.run(cypher_query) persons = [r.data() for r in results] return jsonify(persons) if __name__ == '__main__': app.run(debug=True) 啟動 API: 執行 python app.py 後,可在瀏覽器或 Postman 上測試 http://127.0.0.1:5000/persons。 5. Neo4j 與 RAG (Retrieval-Augmented Generation) 5.1 RAG 概念 RAG:在 Large Language Model (LLM) 無法儲存龐大資料的情況下,將外部知識庫(如資料庫、檔案系統、向量資料庫、圖資料庫)與 LLM 結合。 用圖資料庫的好處: 能表達複雜的關係與上下文。 更直覺地做知識圖譜 (Knowledge Graph) 的連結查詢。 5.2 GraphRAG 的應用 GraphRAG:藉由圖資料庫提供的關聯路徑或上下文資料,讓 LLM 在生成答案時能引入更豐富且準確的資訊。 實作思路: 使用者的問題 -> 先到 Neo4j 查詢相關節點與關係 -> 將結果打包成上下文 -> 再送到 LLM 做回答。 在 LLM 的 Chain 或 Agent 中,加上一個「圖查詢」工具,如 cypher_query_tool,自動生成並執行 Cypher Query。 5.3 簡易範例 # 假設有個函式 run_cypher(query) 能執行 Cypher 並回傳結果 # 1. 接收使用者輸入 user_question = "請問 Alice 的朋友都住在哪些城市?" # 2. 生成 Cypher(此處只是示意,可透過程式自動生成) cypher_query = """ MATCH (a:Person {name: 'Alice'})-[:FRIEND_OF]->(f:Person) RETURN f.name AS friendName, f.city AS city """ # 3. 執行查詢 results = run_cypher(cypher_query) # 4. 將查詢結果整理成文字上下文 context_text = "" for record in results: context_text += f"{record['friendName']} 住在 {record['city']}\n" # 5. 將 context_text 與 user_question 一起餵給 LLM 做回答 # pseudo-code: answer = LLM.generate_answer(user_question, context_text) 透過此流程,就能讓 LLM 具備「即時」且「圖形化」的關係知識檢索能力。 6. 實作練習與示例 6.1 Python 整合練習 建立一個簡易的 Python 腳本,透過 neo4j 官方驅動連接本機 Neo4j。 撰寫函式 create_person(name, age) 與 find_person_by_name(name),並在程式中測試。 顯示查詢結果,將其轉為 Pandas DataFrame 後做基本分析。 6.2 Web API 練習 使用 Flask 建立一個能查詢 Person 資料的 API。 在 Postman 或瀏覽器中呼叫 API,並確認能正確回傳結果。 若有時間,可加入「新增 / 更新 / 刪除」等端點,完成一個簡易的 CRUD 服務。 6.3 RAG 整合練習 (選用) 構建一個簡單的知識圖,包含數個主題、關鍵字、關係。 用程式碼撰寫一個「先查圖,再問 LLM」的流程。 可測試 ChatGPT API 或其他 LLM,給它查詢結果作為上下文,觀察回答是否更準確。 8. 小結 在本模組,你學習了: 官方與第三方驅動:如何透過程式語言(Python、Node.js 等)與 Neo4j 建立連線並操作圖資料。 資料分析整合:使用 Pandas 或 LOAD CSV 進行資料匯入與查詢結果的匯出。 Web Framework:整合 Flask、Django、Express 等,開發 RESTful API 或 Web 後端服務。 RAG 應用:利用圖資料庫作為知識庫,協助 LLM 查詢並生成更精準的回答。 參考連結 Neo4j Drivers & Language Guides py2neo Flask 官方文件 / Django 官方文件 Node.js Neo4j Driver LangChain Graph RAG Example