在 Microsoft Fabric 中撰寫圖形模式查詢

圖型匹配讓你能用直覺且視覺化的語法描述你想找到的資料結構。 你不是連接表格,而是寫出看起來像是關係本身的模式——節點由邊連接。 本文將指導您如何在 Microsoft Fabric 中撰寫 GQL 樣式查詢,以應對圖形中常見的情境。

範例中使用社群網路範例資料集。 完整模式語法參考,請參見 GQL 圖形模式。

利用本文學習如何構建並組合節點、邊與路徑模式。 關於現成可調整的任務,如尋找無關聯的鄰居或實體,請參見 撰寫常見的 GQL 查詢。 關於篩選、分組與彙總工作流程,請參見 「篩選與彙整圖資料」。

先決條件

匹配直接關係

基本模式會匹配節點類型、特定邊型態及另一種節點類型。 語法看起來像是關係的示意圖。

例如,要將最多 100 人與其所屬公司配對:

MATCH (p:Person)-[:workAt]->(c:Company)
RETURN p.firstName, p.lastName, c.name
LIMIT 100

當你不知道或不在意方向時,可以用無向邊緣圖案。 例如,無論誰發起連結,最多可找到100位共同熟人:

MATCH (a:Person)-[:knows]-(b:Person)
RETURN a.firstName, b.firstName
LIMIT 100

Note

Graph 目前不支援建立無向邊,但你可以用 -[:label]- 語法查詢任意方向的邊。

帶有內聯 WHERE 的過濾模式

當條件定義了哪個節點或邊可參與比對時,請將 WHERE 放在模式內。 使用陳述層級的條件 MATCH ... WHERE,對已完成的比對結果進行後置篩選;如果條件適用於較早陳述所產生的資料列,則使用另一個獨立的 FILTER。 謂詞的擺放可能會改變最短路徑的結果。 欲了解更多資訊,請參閱 「路徑選擇前或後的條件置換」。

例如,要找到1990年前出生,且在名稱以「A」開頭的公司工作的人:

MATCH (p:Person WHERE p.birthday < 19900101)-[:workAt]->(c:Company WHERE c.name STARTS WITH 'A')
RETURN p.firstName, p.lastName, c.name

依據邊屬性過濾,以限制符合條件的關係。 例如,只申報2010年或之後開始在公司工作的人員:

MATCH (p:Person)-[w:workAt WHERE w.workFrom >= 2010]->(c:Company)
RETURN p.firstName, c.name, w.workFrom

匹配多跳關係

使用可變長度的模式在一個表達式中遍歷多個跳點。 使用 {min,max} 語法來指定最小和最大跳數。

例如,要找到多達100名能夠被聯繫的人,這些人在愛麗絲朋友互動的兩到四層級之內:

MATCH (src:Person WHERE src.firstName = 'Alice')-[:knows]->{2,4}(dst:Person)
RETURN dst.firstName, dst.lastName
LIMIT 100

要尋找從 Alice 開始最多 100 個直接和二級連結(一或兩次跳躍):

MATCH (src:Person WHERE src.firstName = 'Alice')-[:knows]->{1,2}(dst:Person)
RETURN DISTINCT dst.firstName, dst.lastName
LIMIT 100

使用路徑模式控制遍歷

預設情況下,GQL 使用 WALK,允許重複節點與邊。 需要更嚴格元素獨特性時,可以用其他路徑模式。

路徑模式 行為 使用時機...
WALK 預設允許重複節點與邊 你想要找出所有在有限範圍內符合條件的步行路徑。
TRAIL 沒有重複的邊緣 你想避免重複追蹤同一條邊,但同一個節點可能會穿過不同的邊。
SIMPLE 除了共用的起點和終點節點外,沒有重複節點,也沒有重複邊 你不希望路徑中間的節點不應重複出現,但可以允許路徑回到起點。 這對於偵測迴圈很有用。
ACYCLIC 無重複節點或邊 你需要確保路徑上沒有任何節點出現超過一次。 用於嚴謹的階層結構、分支,或任何重複訪問節點會產生錯誤結果的遍歷。

WALK 是最寬鬆且 ACYCLIC 限制最嚴格的模式。

對於 SIMPLE 和 ACYCLIC,邊唯一性可由節點唯一性推導出。 SIMPLE路徑可以藉由回到第一個節點而形成封閉路徑,但仍不能重複使用同一條邊。

為了說明差異,請考慮《愛麗絲→鮑勃》→《卡蘿》→鮑勃的路徑:

  • WALK — 允許這條路徑。 節點與邊可以自由重複。
  • TRAIL — 允許此路徑。 Bob 出現兩次,但每次邊的關係都不同(Alice→Bob 和 Carol→Bob 是不同的邊),因此不會重複邊。
  • 簡單 — 阻擋這條路。 Bob 出現不只一次,SIMPLE 只允許某節點在成為路徑的起點和終點(形成封閉路徑循環)時才可重複。 這裡愛麗絲是開始,鮑勃是終點,所以沒有例外。
  • 無循環 — 阻擋這條路徑。 鮑勃在路徑上出現過不只一次。

以下範例展示了如何使用TRAIL來計算在四跳之內通往 Alice 網路中前 100 位可達成員的不同路徑數量:

MATCH TRAIL (src:Person WHERE src.firstName = 'Alice')-[:knows]->{1,4}(dst:Person)
LET personId = dst.id
RETURN personId, dst.firstName, dst.lastName, count(*) AS pathCount
GROUP BY personId, dst.firstName, dst.lastName
ORDER BY pathCount DESC
LIMIT 100

可返回 ACYCLIC 最多100名可從愛麗絲在四跳內抵達的人,且路徑上的每個人都是獨一無二的:

MATCH ACYCLIC (src:Person WHERE src.firstName = 'Alice')-[:knows]->{1,4}(dst:Person)
RETURN dst.firstName, dst.lastName
LIMIT 100

預設 REPEATABLE ELEMENTS 的匹配模式允許同一圖型中不同路徑重複使用一條邊。 當所有路徑中的每個邊綁定都必須互不相同時,請使用 DIFFERENT EDGES 或 DIFFERENT RELATIONSHIPS:

MATCH DIFFERENT EDGES
  (p:Person)-[:knows]->(friend:Person),
  (p)-[:knows]->(other:Person)
RETURN p.firstName, friend.firstName, other.firstName
LIMIT 100

回傳一條最短路徑

ALL 是預設路徑搜尋,並回傳所有匹配的路徑。 使用 ANY SHORTEST 來回傳每對來源-目的地的最短路徑。 以下查詢可找到從愛麗絲到鮑勃的最短路徑:

MATCH p = ANY SHORTEST
  (src:Person WHERE src.firstName = 'Alice')-[:knows]->{1,4}
  (dst:Person WHERE dst.firstName = 'Bob')
RETURN p, path_length(p) AS hopCount

當多個最短路徑相符時,回傳的路徑並非確定性。 ALL SHORTEST 和 ANY 路徑搜尋不受支援。

謂詞的位置可能會改變 ANY SHORTEST 的結果。 內嵌節點與邊謂詞會限制哪些路徑符合資格,而後置濾波器則可以移除所選路徑,而不必選擇較長的路徑。 請參見 路徑選擇前或後的地點謂詞。

Tip

建議採用查詢成本的有限上限,以確保查詢成本可預測。 無界 ALL WALK 圖案不被支援。 帶有 TRAIL、SIMPLE 或 ACYCLIC 的無界模式會因元素唯一性而終止,但仍可能返回許多路徑。 Unbounded ANY SHORTEST WALK 只支援特定的查詢形狀。 請參見 目前的限制。

利用變數的重複使用來表達共享對象

在模式的兩個部分重複使用同一變數會產生隱含的等號限制——兩個參考必須匹配於同一個節點。 這個技巧讓你能表達「透過共享的第三實體尋找連結的實體」。

例如,要找到最多100對彼此認識且在同一家公司工作的人的步驟如下:

MATCH (c:Company)<-[:workAt]-(a:Person)-[:knows]-(b:Person)-[:workAt]->(c)
RETURN a.firstName, b.firstName, c.name
LIMIT 100

變數 c 會重複用於兩個 workAt 目標,因此查詢只會回傳雙方彼此認識 且 在同一家公司工作的配對。

要找到多達100對同時按讚同一貼文的人:

MATCH (a:Person)-[:likes]->(post:Post)<-[:likes]-(b:Person)
WHERE a.id < b.id
RETURN a.firstName, b.firstName, post.id
LIMIT 100

Tip

此 WHERE a.id < b.id 條件防止重複配對(Alice + Bob 與 Bob + Alice)出現在結果中。

結合多種圖案

在一個 MATCH中列出多個模式,中間用逗號分隔。 當模式必須綁定相同的圖形元素時,請重用變數。

例如,要找到最多100人及其工作地點及居住城市:

MATCH (p:Person)-[:workAt]->(c:Company),
      (p)-[:isLocatedIn]->(city:City)
RETURN p.firstName, c.name AS company, city.name AS city
LIMIT 100

共享變數 p 連接了這兩個模式。 每一列結果代表一個人及其公司和城市。

不連通的模式同樣有效,但它們會形成其匹配結果的笛卡兒積。 只有在你有意需要所有組合時才使用。 效能指引請參見 「使用共享變數以促進高效連接」。

配對可選關係

若每個節點不一定都存在關係,請使用 OPTIONAL MATCH。 沒有匹配的行會保留 NULL 的值,這類似於 SQL 的 LEFT JOIN。

例如,回傳最多100個人,並顯示他們的公司名稱,其中包括那些公司欄位顯示NULL的無雇主者:

MATCH (p:Person)
OPTIONAL MATCH (p)-[:workAt]->(c:Company)
RETURN p.firstName, p.lastName, c.name AS company
LIMIT 100

使用 IS NULL After OPTIONAL MATCH 可以找到最多 100 位不在任何公司工作的員工:

MATCH (p:Person)
OPTIONAL MATCH (p)-[:workAt]->(c:Company)
FILTER c IS NULL
RETURN p.firstName, p.lastName
LIMIT 100