本文提供 Microsoft Fabric 常見圖形任務的實用 GQL 查詢模式:尋找鄰居、遍歷多跳連線、識別共享連線、計數關係,以及尋找無連接的實體。
範例中使用社群網路範例資料集。 關於查詢流程與語句的端對端說明,請參閱 GQL 語言指南。 當你知道想要完成的圖形任務時,請使用這篇文章。 關於構建節點、邊與路徑模式的系統性教學,請參見 寫入圖模式查詢。 如需詳細的過濾與聚合工作流程,請參見 「過濾與彙整圖資料」。
先決條件
尋找直接鄰居
回傳所有與起始節點一跳連接的節點。
找出特定個人認識的所有人:
MATCH (p:Person WHERE p.firstName = 'Alice')-[:knows]->(friend:Person)
RETURN friend.firstName, friend.lastName
查找該人曾任職的所有公司:
MATCH (p:Person WHERE p.firstName = 'Alice')-[:workAt]->(c:Company)
RETURN c.name, c.url
尋找朋友的朋友(多層網絡)
使用可變長度的模式 {min,max} 來穿越多次跳躍。
找出從愛麗絲出發,剛好經過 knows 條邊可到達的人:
MATCH (alice:Person WHERE alice.firstName = 'Alice')-[:knows]->{2,2}(fof:Person)
RETURN DISTINCT fof.firstName, fof.lastName
LIMIT 100
找到能在三度內聯絡到的每個人:
MATCH (src:Person WHERE src.firstName = 'Alice')-[:knows]->{1,3}(dst:Person)
RETURN DISTINCT dst.firstName, dst.lastName
LIMIT 100
找出從愛麗絲到每位四跳內可達的人的最短路徑:
MATCH p = ANY SHORTEST
(src:Person WHERE src.firstName = 'Alice')-[:knows]->{1,4}(dst:Person)
RETURN dst.firstName, dst.lastName, path_length(p) AS hopCount
ORDER BY hopCount, dst.lastName
LIMIT 100
如果有多條最短路徑以相同的跳數到達同一個人,ANY SHORTEST 會回傳其中一條,但不會以確定性的方式決定要選哪一條。
內聯謂詞限制哪些路徑符合 ANY SHORTEST。
後置過濾器會在選擇最短路徑後生效。 例如,請參見「 路徑選擇前或後置謂詞」。
Tip
使用有限的上界來表示可預測的查詢成本。 無界 ALL WALK 穿越不被支援。 其他無界路徑模式仍能產生大量結果。 請參見 目前的限制。
計算每個實體的關係數量
用 GROUP BY 和 count(*) 計算每個實體擁有多少關係。
關於詳細的分組、聚合過濾及條件路由模式,請參見 篩選與聚合圖資料。
數每個人有多少朋友,依序從多到少:
MATCH (p:Person)-[:knows]->(friend:Person)
LET personId = p.id, name = p.firstName || ' ' || p.lastName
RETURN personId, name, count(*) AS friendCount
GROUP BY personId, name
ORDER BY friendCount DESC
LIMIT 20
為每個實體計算一個價值
使用相關的 CALL 子查詢來計算每個輸入列的值。 外部查詢的變數隱含於子查詢中。
計算每個人的朋友數量:
MATCH (p:Person)
CALL {
MATCH (p)-[:knows]->(friend:Person)
RETURN count(*) AS friendCount
}
RETURN p.firstName, p.lastName, friendCount
ORDER BY friendCount DESC
外部變數在 後 CALL仍可用。 在子查詢中建立的變數中,只有回傳欄位能在子查詢外可用。 當不存在相符的朋友時,未分組的 count(*) 會傳回 0,因此此查詢會保留沒有朋友的人。
當子查詢未傳回任何資料列時,Ordinary CALL 會捨棄一個外部資料列;而當子查詢傳回多筆資料列時,會針對子查詢中的每一筆資料列產生一筆輸出資料列。 當你需要保留沒有相符子查詢資料列的外部資料列時,請使用 OPTIONAL CALL。
尋找共享連結
在模式的兩個部分重複使用變數會產生隱含的「同一節點」限制。 利用此限制尋找透過共享第三實體連接的實體。
找一對彼此都認識同一個人的人:
MATCH (a:Person)-[:knows]->(mutual:Person)<-[:knows]-(b:Person)
WHERE a.id < b.id
RETURN a.firstName, b.firstName, mutual.firstName AS sharedContact
LIMIT 100
請尋找在同一家公司工作的人員組成配對:
MATCH (c:Company)<-[:workAt]-(a:Person), (c)<-[:workAt]-(b:Person)
WHERE a.id < b.id
RETURN a.firstName, b.firstName, c.name AS company
LIMIT 100
Tip
此 WHERE a.id < b.id 條件防止重複配對(Alice–Bob 與 Bob–Alice)出現在結果中。
尋找沒有關係的實體
使用 NOT EXISTS 尋找其相關子查詢未傳回任何資料列的節點。
查找未在任何公司工作的人:
MATCH (p:Person)
WHERE NOT EXISTS {
MATCH (p)-[:workAt]->(c:Company)
RETURN c
}
RETURN p.firstName, p.lastName
LIMIT 100
尋找無留言的貼文:
MATCH (post:Post)
WHERE NOT EXISTS {
MATCH (comment:Comment)-[:replyOf]->(post)
RETURN comment
}
RETURN post.id, post.content
LIMIT 100
尋找有許多關聯的實體
合併 GROUP BY 並 FILTER 識別高度連結的節點。 此方法有助於尋找樞紐或離群值。
尋找有超過10個朋友的人:
MATCH (p:Person)-[:knows]->(friend:Person)
LET personId = p.id, name = p.firstName || ' ' || p.lastName
RETURN personId, name, count(*) AS friendCount
GROUP BY personId, name
FILTER friendCount > 10
ORDER BY friendCount DESC
Note
在 SQL 中,FILTER 之後 GROUP BY 的運作方式就像 HAVING。 它會過濾彙整結果,而不是單一列。