图遍历查询 #
一、图遍历概述 #
1.1 什么是图遍历 #
图遍历是沿着图的边从一个顶点移动到另一个顶点的过程:
text
图遍历类型:
├── 深度优先遍历 (DFS)
├── 广度优先遍历 (BFS)
├── 路径查询
└── 图算法
1.2 OrientDB遍历特点 #
text
遍历特点:
├── 支持SQL语法
├── 支持多种遍历策略
├── 支持条件过滤
├── 支持深度限制
└── 支持路径追踪
二、TRAVERSE语句 #
2.1 基本语法 #
sql
TRAVERSE <fields>
FROM <target>
[STRATEGY <strategy>]
[MAXDEPTH <depth>]
[WHILE <condition>]
[LIMIT <limit>]
2.2 基本遍历 #
sql
TRAVERSE out() FROM #12:0
TRAVERSE out('KNOWS') FROM #12:0
TRAVERSE in() FROM #12:0
TRAVERSE both() FROM #12:0
2.3 遍历策略 #
sql
TRAVERSE out() FROM #12:0 STRATEGY DEPTH_FIRST
TRAVERSE out() FROM #12:0 STRATEGY BREADTH_FIRST
策略说明:
| 策略 | 说明 |
|---|---|
| DEPTH_FIRST | 深度优先,沿一条路径走到底 |
| BREADTH_FIRST | 广度优先,逐层遍历 |
2.4 限制深度 #
sql
TRAVERSE out('KNOWS') FROM #12:0 MAXDEPTH 2
TRAVERSE out('KNOWS') FROM #12:0 MAXDEPTH 3
2.5 条件遍历 #
sql
TRAVERSE out('KNOWS') FROM #12:0 WHILE $depth <= 3
TRAVERSE out('KNOWS') FROM #12:0 WHILE @class = 'Person'
2.6 遍历多个边类型 #
sql
TRAVERSE out('KNOWS', 'WORKS_AT') FROM #12:0
TRAVERSE both('KNOWS', 'FRIEND_OF') FROM #12:0
2.7 遍历返回字段 #
sql
TRAVERSE name, age, out('KNOWS') FROM #12:0
SELECT name, age FROM (TRAVERSE out('KNOWS') FROM #12:0)
三、路径变量 #
3.1 内置路径变量 #
| 变量 | 说明 |
|---|---|
| $path | 完整路径 |
| $depth | 当前深度 |
| $current | 当前顶点 |
| $parent | 父顶点 |
| $previous | 前一个顶点 |
3.2 使用路径变量 #
sql
SELECT
name,
$path AS path,
$depth AS depth
FROM (
TRAVERSE out('KNOWS') FROM #12:0 MAXDEPTH 3
)
3.3 路径格式 #
sql
SELECT
name,
$path AS path
FROM (
TRAVERSE out('KNOWS') FROM #12:0 MAXDEPTH 2
)
输出示例:
text
name: Jerry
path: (#12:0)--KNOWS-->(#12:1)
3.4 深度过滤 #
sql
SELECT name, $depth AS depth
FROM (
TRAVERSE out('KNOWS') FROM #12:0 MAXDEPTH 3
)
WHERE $depth = 2
四、SELECT遍历 #
4.1 使用out/in函数 #
sql
SELECT out('KNOWS').name FROM Person WHERE name = 'Tom'
SELECT out('KNOWS').out('KNOWS').name FROM Person WHERE name = 'Tom'
4.2 指定深度范围 #
sql
SELECT out('KNOWS')[0].name AS friend FROM Person WHERE name = 'Tom'
SELECT out('KNOWS')[0-2].name AS friends FROM Person WHERE name = 'Tom'
SELECT out('KNOWS')[0,2].name AS friends FROM Person WHERE name = 'Tom'
4.3 遍历所有层级 #
sql
SELECT out('KNOWS')[0-].name FROM Person WHERE name = 'Tom'
4.4 条件遍历 #
sql
SELECT out('KNOWS')[age > 25].name FROM Person WHERE name = 'Tom'
五、最短路径 #
5.1 shortestPath函数 #
sql
SELECT shortestPath(#12:0, #12:5)
SELECT shortestPath(#12:0, #12:5, 'OUT')
SELECT shortestPath(#12:0, #12:5, 'BOTH')
5.2 指定边类型 #
sql
SELECT shortestPath(#12:0, #12:5, 'BOTH', 'KNOWS')
SELECT shortestPath(#12:0, #12:5, 'OUT', 'KNOWS', 'WORKS_AT')
5.3 获取路径详情 #
sql
SELECT expand(shortestPath(#12:0, #12:5))
SELECT name FROM (SELECT expand(shortestPath(#12:0, #12:5)))
5.4 最短路径长度 #
sql
SELECT SIZE(shortestPath(#12:0, #12:5)) AS pathLength
六、所有路径查询 #
6.1 allShortestPaths #
sql
SELECT allShortestPaths(#12:0, #12:5)
SELECT allShortestPaths(#12:0, #12:5, 'BOTH', 'KNOWS')
6.2 限制路径数量 #
sql
SELECT allShortestPaths(#12:0, #12:5, 'BOTH', 'KNOWS', 3)
七、图算法 #
7.1 度中心性 #
sql
SELECT
name,
SIZE(bothE()) AS degree
FROM Person
ORDER BY degree DESC
7.2 入度/出度 #
sql
SELECT
name,
SIZE(inE('KNOWS')) AS inDegree,
SIZE(outE('KNOWS')) AS outDegree,
SIZE(bothE('KNOWS')) AS totalDegree
FROM Person
ORDER BY totalDegree DESC
7.3 共同邻居 #
sql
SELECT
intersection(
(SELECT out('KNOWS') FROM Person WHERE name = 'Tom'),
(SELECT out('KNOWS') FROM Person WHERE name = 'Jerry')
) AS mutualFriends
7.4 Jaccard相似度 #
sql
LET $tomFriends = (SELECT out('KNOWS') FROM Person WHERE name = 'Tom')
LET $jerryFriends = (SELECT out('KNOWS') FROM Person WHERE name = 'Jerry')
SELECT
SIZE(intersection($tomFriends, $jerryFriends)) * 1.0 /
SIZE(union($tomFriends, $jerryFriends)) AS jaccardSimilarity
7.5 PageRank模拟 #
sql
SELECT
name,
SIZE(in('KNOWS')) AS incomingLinks,
SIZE(in('KNOWS')) * 1.0 / (SELECT COUNT(*) FROM Person) AS pageRank
FROM Person
ORDER BY pageRank DESC
八、复杂遍历示例 #
8.1 社交网络分析 #
sql
SELECT
name,
SIZE(out('KNOWS')) AS friendCount,
SIZE(out('KNOWS').out('KNOWS')) AS friendsOfFriendsCount,
SIZE(intersection(out('KNOWS'), out('KNOWS').out('KNOWS'))) AS mutualFriendsCount
FROM Person
ORDER BY friendCount DESC
8.2 影响力分析 #
sql
SELECT
name,
SIZE(in('FOLLOWS')) AS followers,
SIZE(out('FOLLOWS')) AS following,
SIZE(in('FOLLOWS')) - SIZE(out('FOLLOWS')) AS influence
FROM User
ORDER BY influence DESC
LIMIT 10
8.3 推荐好友 #
sql
LET $tom = SELECT FROM Person WHERE name = 'Tom'
LET $tomFriends = $tom.out('KNOWS')
LET $friendsOfFriends = $tomFriends.out('KNOWS')
SELECT
name,
COUNT(*) AS mutualFriendCount
FROM $friendsOfFriends
WHERE @rid NOT IN $tomFriends AND @rid != $tom[0].@rid
GROUP BY @rid
ORDER BY mutualFriendCount DESC
LIMIT 5
8.4 知识图谱推理 #
sql
SELECT
e.name AS entity,
out('RELATED_TO').name AS relatedEntities,
out('RELATED_TO').out('RELATED_TO').name AS indirectlyRelated
FROM Entity e
WHERE e.type = 'Concept'
九、遍历优化 #
9.1 使用索引 #
sql
CREATE INDEX Person.name UNIQUE
SELECT FROM Person WHERE name = 'Tom'
9.2 限制深度 #
sql
TRAVERSE out('KNOWS') FROM #12:0 MAXDEPTH 3
9.3 限制结果 #
sql
SELECT FROM (TRAVERSE out('KNOWS') FROM #12:0) LIMIT 100
9.4 条件过滤 #
sql
TRAVERSE out('KNOWS') FROM #12:0 WHILE $depth < 4 AND @class = 'Person'
9.5 使用RID #
sql
TRAVERSE out('KNOWS') FROM #12:0
十、实际应用示例 #
10.1 社交网络好友推荐 #
sql
LET $user = SELECT FROM User WHERE id = 'user_001'
LET $friends = $user.out('FOLLOWS')
LET $friendsOfFriends = $friends.out('FOLLOWS')
SELECT
u.name,
u.username,
COUNT(*) AS mutualFriends
FROM $friendsOfFriends u
WHERE u.@rid NOT IN $friends AND u.@rid != $user[0].@rid
GROUP BY u
ORDER BY mutualFriends DESC
LIMIT 10
10.2 组织架构层级查询 #
sql
SELECT
name,
$depth AS level,
$path AS path
FROM (
TRAVERSE out('REPORTS_TO') FROM (SELECT FROM Employee WHERE title = 'CEO')
STRATEGY BREADTH_FIRST
MAXDEPTH 5
)
ORDER BY $depth
10.3 产品推荐 #
sql
LET $user = SELECT FROM Customer WHERE id = 'customer_001'
LET $purchasedProducts = $user.out('PURCHASED')
LET $similarUsers = (SELECT FROM Customer WHERE out('PURCHASED') IN $purchasedProducts)
SELECT
p.name AS productName,
COUNT(*) AS recommendationScore
FROM $similarUsers.out('PURCHASED') p
WHERE p.@rid NOT IN $purchasedProducts
GROUP BY p
ORDER BY recommendationScore DESC
LIMIT 10
10.4 欺诈检测 #
sql
SELECT
a.name AS person1,
b.name AS person2,
SIZE(shortestPath(a.@rid, b.@rid)) AS distance
FROM Person a, Person b
WHERE a.@rid < b.@rid
AND SIZE(shortestPath(a.@rid, b.@rid)) <= 3
AND a.suspicious = true
AND b.suspicious = true
10.5 知识图谱问答 #
sql
LET $entity = SELECT FROM Entity WHERE name = 'Python'
SELECT
$entity.name AS subject,
out('RELATED_TO').name AS relatedEntity,
out('RELATED_TO').out('RELATED_TO').name AS secondLevelRelated
FROM $entity
十一、总结 #
图遍历查询要点:
| 操作 | 语法 | 说明 |
|---|---|---|
| 遍历 | TRAVERSE | 图遍历操作 |
| 出边 | out() | 出边遍历 |
| 入边 | in() | 入边遍历 |
| 最短路径 | shortestPath() | 最短路径查询 |
| 路径变量 | $path, $depth | 路径信息 |
下一步,让我们学习索引管理!
最后更新:2026-03-27