在 Microsoft Fabric 中撰寫常見的 GQL 查詢

本文提供 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。 它會過濾彙整結果,而不是單一列。