GQL(圖查詢語言)是ISO標準化的圖形資料庫查詢語言。 使用 GQL 在 Microsoft Fabric 中以圖形系統有效率地查詢、分析並處理圖形資料。
同一個標準化 SQL 的 ISO 工作小組也開發了 GQL。 因此,GQL 與 SQL 共享許多概念,包括表達式、謂詞與資料型別。 如果你有 SQL 經驗,很多知識可以應用到 GQL。
本文為圖形中GQL的端到端指南。 它說明語言如何相互銜接,並連結到專注的參考文獻以提供完整的語法和型別細節。 內容涵蓋:
- 核心概念:圖資料結構、模式與查詢基礎
-
基本陳述:
MATCH、、FILTER、WHENLETORDER BYLIMITRETURN - 資料型態與表達式:值型態、運算子與內建函式
- 進階技術:多語句組合、變數範圍與彙整策略
備註
GQL 的官方國際標準是 ISO/IEC 39075 資訊科技 - 資料庫語言 - GQL。
如果你想要的是任務導向的指導,而非語言攻略,請參考操作指南:
- 撰寫常見的 GQL 查詢 ——鄰居、多跳遍歷、共享連線及實體存在檢查
- 過濾與聚合圖資料 — FILTER、WHERE、GROUP BY 及聚合函數
- 撰寫圖樣查詢 — 多跳模式、路徑模式、變數重用與可選匹配
- 優化 GQL 查詢效能 — 過濾策略、遍歷限制與關鍵約束建議
當你需要完整細節時,請使用專注參考文章:
| 所需的資訊 | 權威文章 |
|---|---|
| 語法一覽 | GQL 快速參考 |
| 節點、邊、路徑與模式組合語法 | GQL 圖形模式 |
| 運算子、謂詞與函數 | GQL 表達式、謂詞與函式 |
| 字面語法、值行為與型別轉換 | GQL 值和值類型 |
| 圖型別定義與約束 | GQL 圖表類型 |
| 目前 ISO GQL 功能涵蓋範圍 | GQL 標準符合性 |
| 目前 Fabric 專屬限制與規範 | 目前限制 |
先決條件
在開始之前,請確保你熟悉以下概念:
- 資料庫 - 具備任何資料庫系統的經驗,如關聯式(SQL)、NoSQL或圖,皆有幫助。
- 圖概念 ——理解連接資料中的節點、邊與關係。
- 查詢基礎 ——了解篩選、排序和聚合等基本查詢概念。
推薦背景:
- 有 SQL 或 openCypher 語言的經驗會讓學習 GQL 語法更容易(這是 GQL 的根源)。
- 熟悉資料建模有助於圖結構設計。
- 了解你對圖形資料的特定使用情境。
你需要什麼:
- 存取具備查詢功能的圖形工作空間。
- 範例數據或願意與我們的社群網路合作範例。
- 用於撰寫查詢的基本文字編輯器。
小提示
如果您是圖形資料庫的新手,請先從 圖形資料模型概觀 開始,再繼續本指南。
GQL 有何特別之處
GQL 專為圖形資料設計,因此其語法直接表達實體之間的連結方式。 SQL 通常透過資料表間的連接來表達關係,而 GQL 則使用類似資料圖的圖形模式。
例如,以下查詢會找到彼此認識且皆出生於1999年之前的人對:
MATCH (person:Person)-[:knows]-(friend:Person)
WHERE person.birthday < 19990101
AND friend.birthday < 19990101
RETURN person.firstName || ' ' || person.lastName AS person_name,
friend.firstName || ' ' || friend.lastName AS friend_name
這個模式 (person:Person)-[:knows]-(friend:Person) 顯示了相符的關係結構。 變數會綁定兩個人,讓查詢能過濾並回傳他們的屬性。
GQL 基本概念
這些概念構成了GQL的基礎:
- 圖 包含帶有標籤和屬性的節點與邊。
- 圖類型 正式定義了圖中允許的節點類型、邊類型及限制條件。
-
查詢 使用如
MATCH、FILTER、RETURN等陳述來處理資料並產生結果。 - 模式 描述相符的圖結構。
- 運算式會 計算、轉換並比較數值。
- 謂詞 是用來測試條件的布林表達式。
- 值型別 定義了查詢可處理的值類型及圖屬性可儲存的值類型。
了解圖表資料
要使用 GQL,你需要了解該語言查詢的標記屬性圖結構。
節點和邊緣:建構區塊
一個標記屬性圖包含兩種圖元素:
- 節點 通常代表實體,例如人員、組織、貼文或產品。
- 邊 代表節點間的連結,例如某人認識另一個人或在公司工作。
每個圖元素都有內部單位、一個或多個標籤,以及一組屬性。 標籤用來分類元素,例如 Person 或 knows。 屬性是名值對,例如 firstName: 'Alice' 或 birthday: 19730108u。 在圖中,一條邊總是只有一個標籤。
每條邊恰好連接兩個節點:一個原點與一個目標節點。 邊的方向是圖結構的一部分。 例如,一條workAt邊可以將原點連接到PersonCompany目標。
備註
Graph 目前不支援建立無向邊。 你可以使用任意有向邊模式(例如 -[:knows]-)。 來查詢現有的有向邊,無論向哪個方向。
圖是良構的:每條邊連接同圖中存在的兩個節點。
圖形模型和圖形類型
Fabric 圖模型定義了圖中可用的節點類型、邊類型、屬性、來源映射及鍵值。 它指定哪些來源資料表列會變成節點和邊,以及這些元素如何連接。 關於建模指導,請參見 「設計圖結構」。
GQL 標準使用 圖型 態來正式描述允許的節點類型、邊型、屬性與約束。 圖型別是 Fabric 圖模型所表示結構的語言層級對應物,但 Graph 目前並未直接接受 GQL 圖型宣告。 關於正式語法與概念,請參見 GQL 圖類型。
本指南中使用的範例圖表
範例使用 社群網路範例資料集,包含人物、地點、組織、訊息、標籤及連接它們的邊緣。
範例圖連接了以下區域:
- 人們認識其他人,在公司工作,也在大學就讀。
- 城市、國家或地區,以及大陸構成一個地理階層。
- 論壇裡有貼文,人們也會發文和留言。
- 標籤用來分類內容並代表人們的興趣。
完整的範例結構請參見 社交網路結構範例。 關於一般的圖概念,請參見有標籤性質圖。
您的第一個 GQL 查詢
現在您已經了解了圖形基礎知識,讓我們看看如何使用 GQL 查詢圖形資料。 這些範例從簡單到複雜構建,向您展示 GQL 的方法如何使圖形查詢變得直觀且強大。
從簡單開始:找到所有人
從最基本的問題開始。 找出圖中所有人物:Person的名字(名字、姓氏)。
MATCH (p:Person)
RETURN p.firstName, p.lastName
此查詢流程如下:
-
MATCH找到所有標記為Person的節點。 -
RETURN顯示他們的名字和姓氏。
新增篩選:尋找特定人員
現在找有特定特徵的人。 在這種情況下,找到所有叫 Alice 的人,並顯示他們的名字和生日。
MATCH (p:Person)
FILTER p.firstName = 'Alice'
RETURN p.firstName, p.lastName, p.birthday
此查詢流程如下:
-
MATCH找到所有標記為 Person 的節點 (p)。 -
FILTER節點(p),其名字是 Alice。 -
RETURN顯示他們的名字、姓氏和生日。
基本查詢結構
基本 GQL 查詢都遵循一致的模式:一系列語句,這些陳述式協同工作以尋找、篩選和傳回資料。
大多數查詢從尋找圖中的模式開始 MATCH ,最後以 RETURN 指定輸出結束。
這裡有一個簡單的查詢,可以找到彼此認識且同一生日的人配對,然後回傳這些朋友配對的總數。
MATCH (n:Person)-[:knows]-(m:Person)
FILTER n.birthday = m.birthday
RETURN count(*) AS same_age_friends
此查詢流程如下:
-
MATCH找到所有彼此認識的節點對Person。 -
FILTER只保留兩人生日相同的配對。 -
RETURN數數存在多少對這樣的朋友。
小提示
你也可以直接在模式中加入 WHERE 子句來過濾。 例如,只 MATCH (n:Person WHERE n.birthday < 19900101)Person 匹配 1990 年之前的節點 birthday 。
GQL支援C樣 // 式行註解、SQL樣式 -- 行註解和C樣 /* */ 式區塊註解。
常見陳述
-
MATCH: 識別要搜尋的圖型態——這裡是你定義你感興趣資料結構的地方。 -
LET:根據匹配資料指派新變數或計算值——將導出欄位加入結果。 -
FOR:將列表展開為列,並可選擇以零為基礎的偏移量或以一為基礎的序數位置。 -
CALL: 為每個輸入列執行內嵌子查詢,並加入該子查詢回傳的欄位。 -
FILTER:透過套用條件縮小結果範圍——移除不符合條件的列。 -
ORDER BY:篩選後的資料排序——根據一個或多個欄位協助組織輸出。 -
OFFSET以及LIMIT:限制回傳的列數——對分頁或頂尖查詢非常有用。 -
RETURN: 指定最終輸出——定義應包含哪些資料於結果集中,並執行彙總。 -
NEXT:開始另一個查詢階段,使用前一階段回傳的欄位。
陳述式如何協同運作
GQL 語句形成一條管線,每個語句處理前一個語句的輸出。 這種序列執行使查詢易於閱讀與除錯,因為執行順序與讀取順序相符。
重點︰
- 語句實際上是依序執行的。
- 每個語句都會轉換資料並將它傳遞給下一個。
- 此過程創造出清晰且可預測的資料流程,簡化複雜的查詢。
-
NEXT開始新的查詢階段。 下一階段僅可用前述陳述所投影RETURN的欄位。 -
UNIONUNION DISTINCT、 、 並UNION ALL合併完整查詢區塊的結果。
備註
陳述句有明確的邏輯順序。 根據這些資料流撰寫查詢,而非依賴特定的物理執行策略。
陳述組成範例
以下 GQL 查詢會找到前 10 位在公司名稱中帶有「Air」字樣的公司員工,依全名排序,並回傳他們的全名及公司名稱。
-- Data flows: Match → Let → Filter → Order → Limit → Return
MATCH (p:Person)-[:workAt]->(c:Company) -- Input: unit table, Output: (p, c) table
LET fullName = p.firstName || ' ' || p.lastName -- Input: (p, c) table, Output: (p, c, fullName) table
FILTER c.name CONTAINS 'Air' -- Input: (p, c, fullName) table, Output: filtered table
ORDER BY fullName -- Input: filtered table, Output: sorted table
LIMIT 10 -- Input: sorted table, Output: top 10 rows table
RETURN fullName, c.name AS companyName -- Input: top 10 rows table
-- Output: projected (fullName, companyName) result table
此查詢流程如下:
-
MATCH找到在公司工作的人。 -
LET透過結合名字與姓氏來創造全名。 -
FILTER只保留公司名稱中帶有「Air」字樣的公司員工。 -
ORDER BY依全名排序。 -
LIMIT先取前10個結果。 -
RETURN回傳全名及公司名稱。
變數連接您的資料
變數,如 p、 c,在 fullName 前述範例中,會在語句間傳遞資料。 當您重複使用變數名稱時,GQL 會自動確保它引用相同的數據,從而建立強大的聯結條件。 變數有時也稱為繫結變數。
你可以用不同方式分類變數:
依綁定來源:
- 模式變數 - 由相符的圖形模式所束縛
- 常規變數 - 受其他語言結構約束
模式變數類型:
-
元素變數 - 繫結至圖形元素參考值
- 節點變數 - 繫結至個別節點
- 邊緣變數 - 繫結至個別邊緣
- 路徑變數 - 繫結至代表相符路徑的路徑值
按參考程度:
- 單一變數 - 從型樣繫結至個別元素參考值
- 群組變數 - 綁定到可變長度模式中的元素參考值清單。 詳情請參見 聚合函數。
執行結果和結果
當您執行查詢時,您會傳回包含下列內容的 執行結果 :
-
一個結果,通常是包含你
RETURN語句資料的結果表。 - 顯示查詢是否成功狀態的資訊。
結果表格
結果表格 (如果存在) 是查詢執行的實際結果。
結果表格包括其直欄的名稱和類型、用來顯示結果的慣用直欄名稱序列、表格是否排序, 以及實際列本身的相關資訊。
備註
若執行失敗,執行結果中不會包含任何結果表。
省略的結果
GQL 也為那些從未產生列的語句定義了省略結果,這些陳述與資料或評估結果無關。 遺漏結果的成功完成狀態代碼 00001為 。
省略結果與空結果表不同。 空資料表表示已評估產生列的查詢,但未產生任何列。 查詢 API 可以表示遺漏結果,結果類型 NOTHING為 。
圖會保留遺漏結果,供未來的資料定義語言(DDL)及資料操作語言(DML)陳述式支援使用。 目前的查詢語句會產生資料表結果,包括空資料表。
狀態資訊
在查詢執行過程中,程序會偵測各種值得注意的狀況,例如錯誤或警告。 每個條件由執行結果的狀態資訊中的狀態物件記錄。
狀態資訊包含一個主要狀態物件及一個(可能為空的)其他狀態物件清單。 主要狀態物件始終存在,並指示查詢執行是否成功。
每個狀態物件都包含一個五字元的字母數字代碼及記錄狀況的描述。
查詢 API 使用以下主要狀態碼:
| API 狀態碼 | Meaning |
|---|---|
00000 |
成功完成且至少有一排。 |
00001 |
成功完成但結果未公布。 預留給未來的 DDL 和 DML 支援。 |
01000 |
警告或資訊性狀況。 |
02000 |
目前沒有來自產生列查詢的資料列。 |
42000 |
一個使用者可修正的查詢錯誤。 |
50000 |
系統或非機密錯誤。 |
API 會保留查詢引擎 _graphaneGqlStatus 在診斷記錄成員中報告的典型 GQLSTATUS。 例如,數值溢位使用典範的 GQLSTATUS 22003,而除以零則使用 22012;兩者在公共status.code欄位中皆表示42000。
這很重要
在應用程式程式碼中,用於 status.code 廣泛成功與錯誤處理。 當你需要區分特定查詢條件時,可以使用典型的 GQLSTATUS 診斷工具。 不要測試描述文字,因為它可能會有所不同。
此外,狀態物件可以包含底層的原因狀態物件,以及帶有進一步描述記錄狀況的診斷紀錄。
基本概念和陳述
本節涵蓋撰寫有效 GQL 查詢所需的核心建置區塊。 每個概念都建立為實用的查詢寫作技能。
圖譜模式:尋找結構
圖譜模式描述了要匹配的節點、邊和路徑。 當後續陳述句需要參考匹配元素時,綁定變數:
MATCH (person:Person)-[employment:workAt]->(company:Company)
RETURN person.firstName, company.name, employment.workFrom
當謂詞定義哪個節點或邊可以參與模式時,將謂詞置於內聯:
MATCH (person:Person WHERE person.firstName = 'Alice')
-[:knows]->(friend:Person)
RETURN friend.firstName, friend.lastName
重複使用變數,要求兩個模式位置綁定同一元素。
用逗號分開模式,組成較大的圖結構。 使用量詞 {1,4} ,例如重複邊形圖案,並匹配可變長度的路徑。
路徑模式控制元件在路徑內的重複使用:
| 路徑模式 | 行為 |
|---|---|
WALK |
允許重複節點和邊。 此模式是預設模式。 |
TRAIL |
防止重複邊緣。 |
SIMPLE |
防止重複節點,除非共用的第一和最後一個節點。 |
ACYCLIC |
防止所有重複的節點。 |
路徑搜尋前綴控制回傳哪些匹配路徑。
ALL 是預設值。
ANY SHORTEST 為每個來源-目的節點回傳一條最短路徑:
MATCH path = ANY SHORTEST
(source:Person WHERE source.id = 123u)-[:knows]->{1,4}(target:Person)
RETURN target.id, path_length(path) AS hopCount
內線謂詞在選擇路徑前會限制路徑資格。
語句層級 MATCH ... WHERE 及之後 FILTER 的操作稱為後過濾器。
這種區分可能會改變 ANY SHORTEST 結果。
關於明確的節點、邊、路徑、組合、量詞及謂詞-擺放語意,請參見 GQL 圖模式。 關於目前路徑限制,請參見「當前限制」。
核心陳述
GQL 提供特定的語句類型,這些陳述式類型可以協同工作,逐步處理您的圖形資料。 理解這些陳述對於建立有效的查詢至關重要。
MATCH 陳述
Syntax:
MATCH <graph pattern>, <graph pattern>, ... [ WHERE <predicate> ]
該 MATCH 陳述會接收輸入資料並尋找圖形模式。 它將輸入變數與模式變數連接,輸出則全部為匹配的組合。
輸入和輸出變數:
-- Input: unit table (no columns, one row)
-- Pattern variables: p, c
-- Output: table with (p, c) columns for each person-company match
MATCH (p:Person)-[:workAt]->(c:Company)
使用WHERE進行語句層級過濾:
-- Filter pattern matches
MATCH (p:Person)-[:workAt]->(c:Company) WHERE p.lastName = c.name
你可以用 WHERE後過濾所有匹配。 這種方法避免了獨立 FILTER 陳述。 使用路徑 ANY SHORTEST搜尋前綴如 ,則在路徑選擇後,語句層 WHERE 級會適用。 內線謂詞則限制哪些路徑有資格被選取。 欲了解更多資訊,請參閱 「路徑選擇前或後的條件置換」。
透過輸入變數連接:
當不是第一個陳述式時 MATCH ,它會將輸入資料與模式比對結合:
...
-- Input: table with 'targetCompany' column
-- Implicit join: targetCompany (equality join)
-- Output: table with (targetCompany, p, r) columns
MATCH (p:Person)-[r:workAt]->(targetCompany)
這很重要
圖支援基本及完整線性陳述組合,包括 NEXT。 你也可以將查詢 UNION區塊與 、 UNION DISTINCT、 UNION ALL、 合併。
EXCEPT、 INTERSECT和 OTHERWISE 集合運算尚未被支援。 欲了解更多資訊,請參閱關於 當前限制的文章。
關鍵加入行為:
如何 MATCH 處理資料聯結:
- 變數等式:輸入變數透過等號匹配與模式變數結合
-
內連接:未符合模式的輸入列會被丟棄。 用於
OPTIONAL MATCH左外連接行為。 -
過濾順序:模式匹配與路徑選擇完成後的語句層
WHERE級篩選 - 模式組成:共享變數限制模式在同一元素內。 不連通的圖案形成笛卡兒積。
這很重要
不連通的圖案是有效的,但其笛卡兒積可以產生許多行。 當模式應指向相同的圖形元素時,使用共享變數。
將模式與共享變數合併:
-- Shared variable 'p' joins the two patterns
-- Output: people with both workplace and residence data
MATCH (p:Person)-[:workAt]->(c:Company),
(p)-[:isLocatedIn]->(city:City)
OPTIONAL MATCH 陳述
Syntax:
OPTIONAL MATCH <graph pattern> [ WHERE <predicate> ]
OPTIONAL MATCH 運作方式類似 MATCH ,但使用左外連接語意。 若模式未找到輸入列的匹配,查詢會保留該列 NULL 未匹配變數的值,而非丟棄。
Example:
-- Find all people and, if available, their workplace
MATCH (p:Person)
OPTIONAL MATCH (p)-[:workAt]->(c:Company)
RETURN p.firstName, p.lastName, c.name AS company_name
即使沒有在任何公司工作,結果中仍會出現 。NULLcompany_name
小提示
當你想包含可能沒有特定關聯的實體時,請使用 OPTIONAL MATCH ,類似 SQL LEFT JOIN的 。
LET 陳述
Syntax:
LET <variable> = <expression>, <variable> = <expression>, ...
此 LET 陳述式會建立計算變數,並在查詢管線內啟用資料轉換。
基本變數建立:
MATCH (p:Person)
LET fullName = p.firstName || ' ' || p.lastName
RETURN *
LIMIT 1000
複雜的計算:
MATCH (p:Person)
LET adjustedAge = 2000 - (p.birthday / 10000),
fullProfile = p.firstName || ' ' || p.lastName || ' (' || p.gender || ')'
RETURN *
LIMIT 1000
關鍵行為:
- 查詢引擎會對每個輸入列進行運算式評估。
- 結果會成為輸出表中的新欄位。
- 變數只能參考先前陳述中已有的變數。
- 一個
LET語句中的多個指派會使用相同的輸入範圍,因此一個指派無法從該語句中引用另一個指派。
FOR 陳述
Syntax:
FOR <variable> IN <list_expression>
[ WITH OFFSET <offset_variable> | WITH ORDINALITY <ordinality_variable> ]
該 FOR 陳述式會將清單展開成多列。 對於每個輸入列,它會為每個列表元素輸出一列,並將該元素綁定到指定的變數。 輸入列中的其他變數仍然可用。
用 WITH OFFSET 來綁定以零為基礎的指標,或用來 WITH ORDINALITY 綁定以一為基礎的位置。
LET cities = ['Seattle', 'London', 'Tokyo']
FOR city IN cities WITH ORDINALITY position
RETURN city, position
此查詢會為每個城市回傳一列。 這些值分別為 position1、 2、 3和 。 若將 替換 WITH ORDINALITY position 為 WITH OFFSET position,值為 0、 1、 2和 。
來源表達式必須評估為一個清單。 非列表值會導致查詢失敗。
CALL 陳述
用來 CALL 對每個輸入列執行內嵌子查詢:
CALL {
<query statements>
RETURN <columns>
}
已經在作用域中的變數則隱含地存在於子查詢中。 在子查詢中建立的變數中,只有其最終 RETURN 陳述式中的欄位能在子查詢之外使用。 在子查詢中建立但未回傳的變數仍保持本地狀態。
以下相關子查詢計算每位員工的雇主數量:
MATCH (p:Person)
CALL {
MATCH (p)-[:workAt]->(company:Company)
RETURN count(*) AS employerCount
}
RETURN p.firstName, p.lastName, employerCount
ORDER BY employerCount DESC
普通 CALL 人就像是依賴的內接。 它對子查詢回傳的每一列產生一列輸出資料。 若子查詢未回傳任何列,則對應的外排也不會回傳。 如果回傳多列,則每個子查詢列會顯示最外側的列一次。
前述 count(*) 範例總是回傳一個子查詢列,因為它使用了未分組的聚合。 因此,沒有匹配雇主的人擁有 employerCount 的 0。
作為依賴的左加入使用 OPTIONAL CALL 。 當子查詢未回傳任何列時,會保留一列外側,並將回傳的子查詢欄位設為 NULL。 當子查詢回傳多列時,會為每個子查詢列產生一列輸出資料。
MATCH (p:Person)
OPTIONAL CALL {
MATCH (p)-[:workAt]->(company:Company)
RETURN company.name AS companyName
}
RETURN p.firstName, p.lastName, companyName
你可以巢狀內嵌 CALL 子查詢。 巢狀子查詢可以參考其包圍的查詢範圍中的變數。
這很重要
將每個內嵌CALL實體以 結尾。RETURN 圖不支援命名的程序呼叫或明確的變數匯入清單,例如 CALL (p) { ... }。
FILTER 陳述
Syntax:
FILTER [ WHERE ] <predicate>
此 FILTER 陳述式可讓您精確控制哪些資料會透過查詢管線進行。
基本過濾:
MATCH (p:Person)
FILTER p.birthday < 19980101 AND p.gender = 'female'
RETURN *
複雜的邏輯條件:
MATCH (p:Person)
FILTER (p.gender = 'male' AND p.birthday < 19940101)
OR (p.gender = 'female' AND p.birthday < 19990101)
OR p.browserUsed = 'Edge'
RETURN *
Null 感知篩選模式:
使用下列模式來安全地處理 Null 值:
-
檢查值:
p.firstName IS NOT NULL- 有名字 -
驗證資料:
p.id > 0- 有效身分證件 -
處理遺失的資料:
NOT coalesce(p.locationIP, '10.x.x.x') STARTS WITH '10.x.x.x'- 未從本地網路連線 -
組合條件:
AND/OR與複雜邏輯的明確 null 檢查一起使用
謹慎
請記住,涉及空值的條件會傳回 UNKNOWN,這會篩選掉這些列。 當您需要包含 Null 的邏輯時,請使用明確 IS NULL 檢查。
ORDER BY 陳述
Syntax:
ORDER BY <expression> [ ASC | DESC ] [ NULLS FIRST | NULLS LAST ],
<expression> [ ASC | DESC ] [ NULLS FIRST | NULLS LAST ], ...
使用計算表達式進行多級排序:
MATCH (p:Person)
RETURN *
ORDER BY p.firstName DESC, -- Primary: by first name (Z-A)
p.birthday ASC, -- Secondary: by age (oldest first)
p.id DESC -- Tertiary: by ID (highest first)
排序中的空值處理:
MATCH (p:Person)
RETURN p.firstName, p.birthday
ORDER BY p.birthday DESC NULLS LAST, p.firstName ASC
排序行為細節:
了解運作方式 ORDER BY :
- 查詢引擎會評估每一列的表達式,然後結果決定列序。
- 多個排序鍵會產生階層式排序(主排序、次排序、第三排序等)。
-
NULLS FIRST將空值置於非空值之前。NULLS LAST將它們置於非零值之後。 - 空置位置與排序方向無關。 如果你沒有指定空序,則
NULLS LAST是 和DESC的預設ASC值。 -
ASC(升序)是預設順序,你必須明確指定DESC(降序)。 - 你可以依計算出的值排序,而不只是儲存的屬性。
| 排序規範 | 結果順序 |
|---|---|
ASC 或 ASC NULLS LAST |
非空值依序遞減,接著是空值。 |
ASC NULLS FIRST |
空值,接著是非空值,依序由高到低排列。 |
DESC 或 DESC NULLS LAST |
非空值由降序排列,接著是空值。 |
DESC NULLS FIRST |
空值,接著是非空值,從高到低排列。 |
謹慎
只有 緊接 著的語句才能看到建立的排序順序 ORDER BY 。
因此, ORDER BY 接著 並 RETURN * 不會產生有序結果。
比:
MATCH (a:Person)-[r:knows]->(b:Person)
LET aName = a.firstName || ' ' || a.lastName
LET bName = b.firstName || ' ' || b.lastName
ORDER BY r.creationDate DESC
/* intermediary result _IS_ guaranteed to be ordered here */
RETURN aName, bName, r.creationDate AS since
/* final result _IS_ _NOT_ guaranteed to be ordered here */
取代為:
MATCH (a:Person)-[r:knows]->(b:Person)
LET aName = a.firstName || ' ' || a.lastName
LET bName = b.firstName || ' ' || b.lastName
/* intermediary result _IS_ _NOT_ guaranteed to be ordered here */
RETURN aName, bName, r.creationDate AS since
ORDER BY r.creationDate DESC
/* final result _IS_ guaranteed to be ordered here */
此差異對「Top-k」查詢有立即影響: LIMIT 必須始終跟隨 ORDER BY 建立預期排序順序的陳述。
OFFSET 和 LIMIT 語句
Syntax:
OFFSET <offset> [ LIMIT <limit> ]
| LIMIT <limit>
常見模式:
-- Basic top-N query
MATCH (p:Person)
RETURN *
ORDER BY p.id DESC
LIMIT 10 -- Top 10 by ID
這很重要
如需可預測的分頁結果,請一律使用 ORDER BY before OFFSET 和 LIMIT 以確保查詢之間的資料列順序一致。
RETURN:基本結果預測
Syntax:
RETURN [ DISTINCT ] <expression> [ AS <alias> ], <expression> [ AS <alias> ], ...
[ ORDER BY <expression> [ ASC | DESC ] [ NULLS FIRST | NULLS LAST ], ... ]
[ OFFSET <offset> ]
[ LIMIT <limit> ]
此 RETURN 陳述式會指定結果資料表中顯示哪些資料,以產生查詢的最終輸出。
基本輸出:
MATCH (p:Person)-[:workAt]->(c:Company)
RETURN p.firstName || ' ' || p.lastName AS name,
p.birthday,
c.name
為了清楚起見,使用別名:
MATCH (p:Person)-[:workAt]->(c:Company)
RETURN p.firstName AS first_name,
p.lastName AS last_name,
c.name AS company_name
結合排序和top-k:
MATCH (p:Person)-[:workAt]->(c:Company)
RETURN p.firstName || ' ' || p.lastName AS name,
p.birthday AS birth_year,
c.name AS company
ORDER BY birth_year ASC
LIMIT 10
使用 DISTINCT 進行重複處理:
-- Remove duplicate combinations
MATCH (p:Person)-[:workAt]->(c:Company)
RETURN DISTINCT p.gender, p.browserUsed, p.birthday AS birth_year
ORDER BY p.gender, p.browserUsed, birth_year
結合彙總:
MATCH (p:Person)-[:workAt]->(c:Company)
RETURN count(DISTINCT p) AS employee_count
RETURN with GROUP BY:分組結果投影
Syntax:
RETURN [ DISTINCT ] <expression> [ AS <alias> ], <expression> [ AS <alias> ], ...
GROUP BY <variable>, <variable>, ...
[ ORDER BY <expression> [ ASC | DESC ], <expression> [ ASC | DESC ], ... ]
[ OFFSET <offset> ]
[ LIMIT <limit> ]
用 GROUP BY 來依共用值將資料列分組,並在每個群組內計算彙總函數。
具有彙總的基本分組:
MATCH (p:Person)-[:workAt]->(c:Company)
LET companyId = c.id, companyName = c.name
RETURN companyId,
companyName,
count(*) AS employeeCount,
avg(p.birthday) AS avg_birth_year
GROUP BY companyId, companyName
ORDER BY employeeCount DESC
多欄分組:
MATCH (p:Person)
LET gender = p.gender
LET browser = p.browserUsed
RETURN gender,
browser,
count(*) AS person_count,
avg(p.birthday) AS avg_birth_year,
min(p.creationDate) AS first_joined,
max(p.id) AS highest_id
GROUP BY gender, browser
ORDER BY avg_birth_year DESC
LIMIT 10
備註
關於可變長度模式的水平聚合,請參見 聚合函數。
值和值類型
GQL 值包括布林值、字串值、數字值、時間值、列表值、節點值、邊值、路徑值、空值及無值值。 型別是可空的,除非你指定 NOT NULL。
屬性使用完整查詢值系統中支援的子集。
RETURN 42 AS integerValue,
'Alice' AS stringValue,
TRUE AS booleanValue,
[1, 2, 3] AS listValue
與虛無的比較評估為UNKNOWN;用於IS NULLIS NOT NULL虛無檢定。 數值運算可以在相容的數值類型間進行隱式轉換。
備註
並非所有 GQL 值類型在每個圖譜上下文中都被支援。 關於目前屬性與查詢限制,請參見 資料型別。
關於字面語法、比較行為、型別轉換及型別階層,請參見 GQL 值與值型別。
Expressions
表達式會計算、比較、彙總並轉換數值。 常見的形式包括屬性參照、算術與邏輯運算子、謂詞、函式呼叫、簡單 CASE 表達式及子查詢:
MATCH (person:Person)
FILTER person.birthday < 19900101
RETURN person.firstName,
CASE person.gender
WHEN 'female' THEN 'F'
WHEN 'male' THEN 'M'
ELSE 'Other'
END AS genderCode
GQL 使用三值邏輯:布林表達式可以評估為 TRUE、 FALSE、 或 UNKNOWN。 A FILTER 只保留其謂詞為 TRUE的列。
彙總函數如 COUNT、 SUM、 AVG、 MIN、 及 MAX 彙整列數。 列表謂詞如 ALL、 ANY、 NONE,並 SINGLE 對列表元素評估謂詞。 程序表單 EXISTS 子查詢測試巢狀查詢是否回傳一列。
關於完整的運算子、謂詞、聚合與函數行為,請參見 GQL 表達式、謂詞與函數。 關於任務導向的過濾與分組範例,請參見 「篩選與聚合圖資料」。
進階查詢技術
本節介紹用於建立複雜、高效的圖形查詢的複雜模式和技術。 這些模式超越基本陳述式用法,可協助您撰寫強大的分析查詢。
複多語句組合
這很重要
圖支援基本及完整線性陳述組合。
EXCEPT、 INTERSECT和 OTHERWISE 集合運算尚未被支援。 欲了解更多資訊,請參閱關於 當前限制的文章。
了解如何有效地撰寫複雜的查詢對於進階圖形查詢至關重要。
UNION 與 UNION ALL
使用 UNION、 UNION DISTINCT或 來 UNION ALL 結合兩個或以上線性查詢區塊的結果:
<query block>
UNION [ DISTINCT | ALL ]
<query block>
-- Combine results from two separate pattern matches
MATCH (p:Person)-[:workAt]->(c:Company)
RETURN p.firstName AS name, c.name AS affiliation
UNION DISTINCT
MATCH (p:Person)-[:studyAt]->(u:University)
RETURN p.firstName AS name, u.name AS affiliation
Bare UNION 等同於 UNION DISTINCT;兩者都會移除重複的行。
UNION ALL 保留所有列,包括重複的列。
每個查詢區塊必須回傳相同的欄位名稱集合。 欄位順序可能因區塊而異,且資料型態必須相容。
NEXT
用 NEXT 來對前一階段返回的資料表執行另一個查詢階段:
<query stage>
RETURN <columns>
NEXT
<query stage>
以下查詢會找到員工及其公司,然後利用回傳的員工節點進行另一個模式匹配:
MATCH (person:Person)-[:workAt]->(company:Company)
RETURN person, company.name AS companyName
NEXT
MATCH (person)-[:isLocatedIn]->(city:City)
RETURN person.firstName AS employee, companyName, city.name AS city
只有前一階段回傳的欄位才在 之後 NEXT的範圍內。 你可以使用多個 NEXT 分隔符來建立更長的查詢階段序列。
任一階段都可以包含查詢區塊的聯集。 在該階段的輸出越過 NEXT 邊界之前,會先在其階段內評估聯合。 若 A、 、 代表C查詢區塊,A UNION B NEXT C分組為 (A UNION B) NEXT C,而A NEXT B UNION C分組為 A NEXT (B UNION C)B。
條件陳述式
使用條件語句將每個輸入的列路由到第一個分支,其謂詞值為 TRUE:
WHEN <predicate> THEN <linear query statement or { query statements }>
[ WHEN <predicate> THEN <linear query statement or { query statements }> ... ]
[ ELSE <linear query statement or { query statements }> ]
要路由前一查詢階段的列,回傳所需的欄位,並在條件語句前使用 NEXT :
MATCH (p:Person)
RETURN p.firstName AS name, p.birthday AS birthday
NEXT
WHEN birthday < 19800101u THEN
RETURN name, 'Before 1980' AS era
WHEN birthday < 20000101u THEN
RETURN name, '1980-1999' AS era
ELSE
RETURN name, '2000 or later' AS era
每個 WHEN 謂詞必須是布林值。 查詢引擎會依序評估每個輸入列的謂詞。 一個條件,評估或FALSEUNKNOWN不選擇其分支。 當謂詞評估到 TRUE後,之後的謂詞和未被選取的分支體則不再被評估。 如果沒有謂詞能應值到 且 TRUE 沒有 ELSE,則輸入列不會回傳。
謂詞與分支實體可參考前一階段的欄位。 分支可以是單一線性陳述,也可以是包裹在大括號中的巢狀程序。 當一個分支需要多個階段或多個陳述式時,使用巢狀程序,例如 CALL:
MATCH (p:Person)
RETURN p, p.firstName AS name
NEXT
WHEN p.gender = 'female' THEN {
CALL {
MATCH (p)-[:knows]->(friend:Person)
RETURN count(*) AS friendCount
}
RETURN name, friendCount
}
ELSE
RETURN name, 0u AS friendCount
每個分支都有自己的地方範圍。 兄弟分支不會看到其他分支所建立的變數,只有所選分支 RETURN 最後的欄位在條件陳述後繼續。 每個分支必須回傳相同的欄位名稱,且對應的結果類型必須相容。 查詢引擎會強制相容型別到共同的輸出型態。 回傳的分支欄位可與輸入欄位使用相同名稱;分支值取代條件輸出中的輸入值。
條件語句與 CASE 表達式不同。 圖譜支援簡單的 CASE <expression> WHEN <value>,但不搜尋 CASE WHEN <predicate> 的表達式。 欲了解更多資訊,請參閱 條件表達式。
可變範圍和進階流量控制
變數跨查詢語句連接資料並啟用複雜的圖形遍歷。 瞭解進階範圍規則可協助您撰寫複雜的多語句查詢。
變數綁定與範圍模式
-- Variables flow forward through subsequent statements
MATCH (p:Person) -- Bind p
LET fullName = p.firstName || ' ' || p.lastName -- Bind concatenation of p.firstName and p.lastName as fullName
FILTER fullName CONTAINS 'Smith' -- Filter for fullNames with “Smith” substring (p is still bound)
RETURN p.id, fullName -- Only return p.id and fullName (p is dropped from scope)
跨敘述的連接時的變數重用
-- Multi-statement joins using variable reuse
MATCH (p:Person)-[:workAt]->(:Company) -- Find people with jobs
MATCH (p)-[:isLocatedIn]->(:City) -- Same p: people with both job and residence
MATCH (p)-[:knows]->(friend:Person) -- Same p: their social connections
RETURN *
關鍵範疇規則與限制
-- ✅ Backward references work
MATCH (p:Person)
LET adult = p.birthday < 20061231 -- Can reference p from previous statement
RETURN *
-- ❌ Forward references don't work
LET adult = p.birthday < 20061231 -- Error: p not yet defined
MATCH (p:Person)
RETURN *
-- ❌ Variables in same LET statement can't reference each other
MATCH (p:Person)
LET name = p.firstName || ' ' || p.lastName,
greeting = 'Hello, ' || name -- Error: name not visible yet
RETURN *
-- ✅ Use separate statements for dependent variables
MATCH (p:Person)
LET name = p.firstName || ' ' || p.lastName
LET greeting = 'Hello, ' || name -- Works: name now available
RETURN *
複雜查詢中的變量可見性
-- Variables remain visible until overridden or query ends
MATCH (p:Person) -- p available from here
LET gender = p.gender -- gender available from here
MATCH (p)-[:knows]->(e:Person) -- p still refers to original person
-- e is a new variable for the friend
RETURN p.firstName AS manager, e.firstName AS friend, gender
謹慎
同一語句中的變數不能互相參照,除非在圖模式中。 使用單獨的陳述式來建立應變數。
聚合列與路徑元素
GQL 支援兩種聚合上下文:
-
垂直聚合 是將輸入列彙總,並可選擇依
GROUP BY變數劃分。 - 水平聚合 總結了一個由可變長度邊型圖樣所界定的群組列表,該群組在一條匹配路徑內。
MATCH (person:Person)-[:workAt]->(company:Company)
LET companyId = company.id, companyName = company.name
RETURN companyId, companyName, count(*) AS employeeCount
GROUP BY companyId, companyName
MATCH (:Person)-[connections:knows]->{1,4}(:Person)
RETURN count(connections) AS pathLength
關於群組查詢、聚合專屬篩選器、集合聚合及條件路由,請參見 篩選與聚合圖資料。 完整的彙總結果規則,請參見 彙總函數。
處理空值與查詢錯誤
當缺失值需要明確處理時,使用明確的空測試:
MATCH (person:Person)
FILTER person.browserUsed IS NULL
RETURN person.firstName
與 null 比較時,得值為 UNKNOWN,a FILTER 不保留此值。
需要備用值時使用 coalesce() 。
查詢結果包括成功狀態資訊、警告、無資料狀況、使用者可修正錯誤及系統錯誤。 使用公開狀態碼進行廣泛的控制流程,並使用標準的 GQLSTATUS 診斷以處理特定狀況。 請參閱 執行結果與結果 ,以及 GQL 狀態碼參考資料。
保留字詞
GQL 會保留某些您無法用作識別碼的關鍵字,例如變數、屬性名稱或標籤名稱。 如需完整清單,請參閱 GQL 保留字組參考 。
如果您需要使用保留字作為標識符,請使用反引號轉義它們: `match`, `return`。
若要避免逸出保留字,請使用此命名慣例:
- 對於單字識別碼,請附加底線:
:Product_ - 對於多字標識符,請使用駝峰命名法或帕斯卡命名法:
:MyEntity,:hasAttribute,textColor
後續步驟
- 請參考 快速入門 或 GQL教學 ,獲得實作入門。
- 使用 撰寫常見的 GQL 查詢 來處理即備可調整的圖形任務。
- 詳細參考 GQL 圖樣、 GQL 表達式、謂詞與函式,以及 GQL 值與值型 別。
- 請使用 Design a Graph schema 來支援 Fabric 建模工作流程。