在 Neo4j 中,Path(路徑) 是連接兩個或多個節點的關系序列,是圖查詢的核心概念之一。理解 Path 的用法對于復雜圖分析至關重要
關鍵特性:
有向性:路徑中的關系具有方向
可變長度:路徑可以包含 0 個或多個關系
類型約束:關系可以指定類型(如 :ACTED_IN)
屬性過濾:節點和關系可以通過屬性過濾
(1)簡單路徑匹配
MATCH p = (a:Person)-[:FRIEND]->(b:Person)
RETURN p
(2)可變長度路徑
MATCH p = (a:Person)-[:FRIEND*2..5]->(b:Person) // 2到5跳的路徑
RETURN p
(3)任意關系類型
MATCH p = (a:Person)-[*]->(b:Person) // 任意類型和長度的關系
RETURN p
(4)特定關系類型組合
MATCH p = (a:Person)-[:ACTED_IN|DIRECTED*]->(m:Movie)
RETURN p
(5)Path 的函數與操作
MATCH p = (a:User)-[:FRIEND*]->(b:User)
RETURN p
// 返回關系數量
MATCH p = (a:User)-[:FRIEND*]->(b:User)
RETURN length(p) AS pathLength
(6)提取路徑節點和關系
MATCH p = (a:User)-[:FRIEND*]->(b:User)
RETURN nodes(p) AS pathNodes, // 返回節點列表relationships(p) AS rels // 返回關系列表
在 Neo4j 的路徑匹配中,*…3 表示 ** 路徑長度(關系數量)** 的范圍,不包含節點自身。具體規則如下:
路徑深度的含義:
*n…m:表示路徑中關系的數量范圍(n 到 m 跳)
不包含節點自身:即使 n=0,也需要至少一個關系才能構成路徑
示例:
*0…3:允許 0 到 3 跳的路徑(但 0 跳路徑無實際意義,因為至少需要一個關系)
*1…3:允許 1 到 3 跳的路徑(最常見的用法)
*…3:等價于 *1…3(默認從 1 開始)
//只查詢Tom Cruise 的person節點指向任一節點,關系邊的長度為1或者2的數據
MATCH path = (p:Person {name: "Tom Cruise"})-[*..2]-(other)
RETURN path
LIMIT 100 // 限制結果數量,避免返回過多路徑
結果如下圖所示
圖展示形式
Text展示形式
//只查詢Tom Cruise 的person節點指向任一節點,關系邊的長度只為3的數據
MATCH path = (p:Person {name: "Tom Cruise"})-[*3..3]-(other)
RETURN path
LIMIT 100 // 限制結果數量,避免返回過多路徑
關鍵參數:
*…2:表示路徑最大深度為 2 跳 (查詢Tom Cruise到任一節點,任一關系路徑為1或者2的數據)
(p:Person {name: “Tom Cruise”}):起始節點
(other):匹配任意類型的節點
//關系類型的路徑查詢
MATCH path = (p:Person {name: "Tom Cruise"})-[r:ACTED_IN|REVIEWED|FOLLOWS*..3]-(other)
RETURN path
LIMIT 100
如上圖所示,p-m,有兩個路徑,一個長度是5,一個長度3,我現在想獲取最短路徑
基本最短路徑查詢
在 Neo4j 中,查找兩個節點之間的最短路徑可以使用 shortestPath 或 allShortestPaths 函數
MATCH (p:Person {name: "Tom Cruise"}), (m:Movie {title: "One Flew Over the Cuckoo's Nest"})
MATCH path = shortestPath((p)-[*]-(m)) // 查找最短路徑
RETURN path
如圖所示:
關鍵參數:
[*]:表示任意類型和長度的關系
shortestPath:返回單條最短路徑
如果存在多條相同長度的最短路徑,僅返回其中一條
//指定關系類型的最短路徑
//如果只關心特定關系類型(如 ACTED_IN、DIRECTED 等):
MATCH (p:Person {name: "Tom Cruise"}), (m:Movie {title: "One Flew Over the Cuckoo's Nest"})
MATCH path = shortestPath((p)-[:ACTED_IN|DIRECTED|REVIEWED|FOLLOWS*]-(m))
RETURN path
//限制路徑深度:如果圖很大,可設置最大深度(但可能錯過真實最短路徑)
MATCH path = shortestPath((p)-[*..10]-(m)) // 最大深度10
Path 的典型應用場景
(7)社交網絡分析
// 查找共同好友(查找Alice和Bob的共同朋友)
MATCH (a:Person {name: "Alice"})-[:FRIEND]-(f:Person)-[:FRIEND]-(b:Person {name: "Bob"})
RETURN f.name AS mutualFriend
(8)推薦系統
// 基于共同興趣推薦
MATCH (u:User {id: 123})-[:LIKES]->(p:Product)<-[:LIKES]-(other:User)
MATCH path = (other)-[:LIKES]->(reco:Product)
WHERE NOT EXISTS((u)-[:LIKES]->(reco))
RETURN reco.name AS recommendation, COUNT(path) AS score
ORDER BY score DESC//該語句分析
1. 從用戶123出發,找到他喜歡的產品集合P
2. 找到所有喜歡P中產品的其他用戶集合U
3. 收集U中用戶喜歡的所有產品集合R
4. 從R中排除用戶123已經喜歡的產品
5. 統計每個剩余產品被多少個U中的用戶喜歡
6. 按統計結果排序,生成推薦列表
(9)知識圖譜路徑分析
// 查找藥物與疾病的關系路徑
MATCH p = (d:Drug)-[:TREATS|INTERACTS|METABOLIZED_BY*]->(dis:Disease)
WHERE d.name = "阿司匹林" AND dis.name = "心臟病"
RETURN p