GQL 指南

使用 “版本 ”下拉列表切换服务。 了解有关导航的详细信息
适用于: ✅ Azure 数据资源管理器

GQL (图形查询语言)是一种 ISO 标准(ISO/IEC 39075:2024),用于通过匹配路径、节点和边缘模式来查询图形。

先决条件

  • 在运行查询之前创建图形并设置图形引用。 请参阅 “创建图形”并设置图形引用。 每个查询都 MATCH以 .. 开头。

  • 使用先决条件中引用的示例电影图形 G()。 该图包含人员节点(名称、出生)、电影节点(标题、说明、年份)和ACTED_IN和 DIRECTED 边缘(角色),标签存储在 Label2 列中。

  • 有关支持子句的完整列表,请参阅 GQL 子句

  • 有关支持函数的完整列表,请参阅 GQL 标量函数

注意

  • 一些示例使用示例电影图中不包含的插图标签。
  • 所有图形查询都以 MATCH 子句开头。

查询基本结构

GQL 查询以子 MATCH 句开头,并遵循管道结构,其中每个子句对上一子句的结果进行操作:

  1. MATCH 在图形中查找模式。
  2. WHERE 筛选匹配的行。
  3. RETURN 投影输出列(可选)和 DISTINCT 聚合。
  4. ORDER BY,然后OFFSETLIMIT对结果进行排序和分页。

将多个语句与复合 MATCH 序列、管道(由一个 NEXT 语句返回的行馈送下一个语句)或 UNION 连接结果组合在一起。

MATCH

MATCH 描述在图形中查找的模式。 模式是由边缘模式连接的节点模式链。 将变量绑定到实体以筛选或返回它们。

每个元素模式(节点或边缘)都可以按标签:Person)、内联属性()和{Year: 1995}WHERE(n:Person WHERE n.Born > 1950)元素内部)进行筛选。

节点模式

节点模式包括括号,可以选择使用变量、标签和内联属性。

图案 匹配
() 任何节点
(m) 绑定到变量的任何节点 m
(:Movie) 标记的节点 Movie
(m:Movie) Movie 节点,绑定到变量 m
(m:Movie {Year: 1995}) Movie 等于 Year 1995 的节点
(p:Adventure & !Horror) 具有标签但不Adventure带标签的Horror节点。 将标签与 &\|!请参阅标签
match (m:Movie) return m.Title as MovieTitle
MovieTitle
m.Title
T1
T2
T3

边缘模式

边缘图案包括两个节点之间的方括号,以及用于设置方向的短划线和箭头。

图案 方向
(a)-[e]->(b) ab
(a)<-[e]-(b) ba
(a)-[e]-(b) 任一方向
(a)->(b)(a)<-(b)(a)-(b) 没有边界边缘的方向
(a)-[e:ACTED_IN \| DIRECTED]->(b) ab,匹配 ACTED_INDIRECTED 边缘。 将标签与 、&\|!(请参阅())组合在一起

简写-><--可用于代替-[]-><-[]--[]-。 边缘变量和标签的工作方式类似于节点:[e]、、[:ACTED_IN][e:ACTED_IN][e {Role: 'Director'}]

match (p:Person)-[:ACTED_IN]->(m:Movie) return p.Name as actor, m.Title as movie
参与者 电影
卢宁 T1
卢宁 T2
卢宁 T3
Kevin T1

对匹配的模式进行计数:

match (p:Person)-[:ACTED_IN]->(m:Movie) return count(*) as patternsCount
patternsCount
4

链接模式

连接多个模式以跟踪多个跃点之间的关系。 使用同一变量多次引用同一个节点。

match (p1:Person)-[:ACTED_IN]->(m:Movie)<-[:ACTED_IN]-(p2:Person)
return p1.Name as firstActor, m.Title as movie, p2.Name as secondActor
firstActor 电影 secondActor
卢宁 T1 Kevin
Kevin T1 卢宁

多个序列(多路径或“星形”模式)

GQL 支持单个 MATCH 子句中的多个逗号分隔模式。 这些模式必须至少共享一个节点变量,因此它们形成一个连接的模式。 例如,以下查询查找在一部电影中表演并导演另一部电影的人员。

match (p:Person)-[:ACTED_IN]->(m:Movie), (p)-[:DIRECTED]->(m2:Movie)
return p.Name as person, m.Title as firstTitle, m2.Title as secondTitle
firstTitle secondTitle
卢宁 T1 T2
卢宁 T2 T2
卢宁 T3 T2

可变长度边缘

使用限定符跟踪多个跃点之间的关系。 将路径分配给变量(p = ...)以返回完整路径,或者使用 p[i] 等表达式引用索引 i 处的特定边缘或节点。

match p = (n1)-[e]->{2,2}(n2) return p
限定符 酒花
{m,n} between m and n hops
{m,} m 或更多跃点
{,n} 最多 n 跃点
{,} 任意数量的跃点
{n} 完全 n
* 零个或多个 (相同 {,}
+ 一个或多个 (相同 {1,}

例:

match (e:Employee)->*(m:Manager) return m.Name as managerName

Labels

标签按类别选择节点和边缘。 筛选后 : 跟标签表达式。 节点模式和边缘模式都支持嵌套在任意深度上的 AND(&)、OR(|和 NOT(!)的任何逻辑组合。 标签名称区分大小写;使用反引号与关键字相撞的引号名称。

对于以下示例,将图形标签名称设置为 Label2创建图形”中所述,并设置图形引用

Operator Meaning
:A has label A
A & B 具有两者
A \| B 具有任一
!A 没有 A

下一个查询查找带有标签 Female的所有实体:

match (p :Female) return p.Name as name
名字
朱莉娅

下一个查询展示组标签表达式:

match ()-[e: !ACTED_IN & (DIRECTED | A) | E]->(m:Movie) return m.Title as title
标题
T1
T2

引用具有两个标签的同一变量,需要两个标签:

match (n:Male), (n:BestActorAward) return n.Name as name
名字
卢宁

labels() 函数将元素的标签作为列表返回。 它在子句中 WHERE 非常有用 RETURN 。 例如,'DIRECTED' IN labels(e)

match (p:Person)-[e:ACTED_IN]->(m:Movie)
return p.Name as name, labels(e) as EdgeLabels
名字 EdgeLabels
卢宁 [“ACTED_IN”]
卢宁 [“ACTED_IN”]
卢宁 [“ACTED_IN”]
Kevin [“ACTED_IN”]

访问节点属性

使用点表示法访问节点或边缘的属性:绑定变量、属性 .名称和属性名称。

match (m:Movie)
return m.Title as title, m.Year as year
标题
T1 1995
T2 2011
T3 2020

[]索引器按列表或路径的整数位置(从零开始),而不是按名称访问属性。 将它与点表示法组合在一起,以读取路径元素的属性。 例如,p[0]路径的第一个节点p,因此p[0].Name返回该节点的 :Name

match p = (:Person)-[:ACTED_IN]->(:Movie)
return p[0].Name as name
名字
卢宁
卢宁
卢宁
Kevin

比较

GQL 支持标量值的标准比较运算符:=、( <> 不等于)、<、、<=>>=

下一个查询从匹配的模式中筛选出标题为“T1”的电影:

match (p:Person)-[:ACTED_IN]->(m:Movie)
where m.Title <> 'T1'
return p.Name as name, m.Title as title
名字 标题
卢宁 T2
卢宁 T3

不能直接比较两个节点或边缘或=<>两个边缘。 若要测试两个实体是否不同,请改为将其标识进行比较 element_id() 。 例如,以下查询查找在同一部电影中出现的不同演员对:

match (p1:Person)-[:ACTED_IN]->(m:Movie)<-[:ACTED_IN]-(p2:Person)
where element_id(p1) <> element_id(p2)
return p1.Name as firstName, p2.Name as secondName, m.Title as title
firstName secondName 标题
卢宁 Kevin T1
Kevin 卢宁 T1

筛选可变长度路径中的边缘

在边缘模式中,标签和 WHERE 筛选器应用于路径上的 每个 边缘;仅保留其跃点全部匹配的路径。

match ()-[e:DIRECTED]->+() return e[0].Name as personName, e[0].Role as personRole
personName personRole
罗恩 主管
卢宁 主管
match ()-[e where 'DIRECTED' in labels(e)]->+() return e[0].Role as role
角色
主管
主管

在模式之外,边缘变量 e 是遍历边缘的数组,因此为它(e[0]e[1]编制索引以访问单个跃点。

以下示例查找不同的角色。 CAST重复数据删除值需要字符串,因为此上下文中未知的类型Role

match ()-[e where 'DIRECTED' in labels(e)]->+() return distinct cast(e[0].Role as string) as role
角色
主管

以下示例查找包含一个或两个跃点的所有模式,并按 Role每个边缘筛选。 该查询返回长度为 1 的所有路径,每个路径都作为 JSON 字符串返回。

match p = (n1)-[e {Role: "Role2"}]->{1,2}(n2)
where path_length(p) = 1
return to_json_string(p) as myPath
myPath
[{“Name”:“Kevin”, ...“说明”:“关于太空的电影”,“年份”:1995}]

运营商

除了比较运算符之外,GQL 还支持算术、串联和布尔逻辑:

  • 算术 (+-:对数值进行操作,对时间点进行加减 timespanduration(...))或从 datetime 中移出时间点。
  • 串联 (||:将两个字符串或两个列表联接到一个值中。
  • 布尔值(AND、、ORNOTIN:将谓词与括号组合在WHERECASE一起,以及其他条件;将它们与括号组合在一起。
match (p:Person)
return p.Name || ' born ' || cast(p.Born as string) as `Label`, p.Born + 1 as NextYear
标签 NextYear
汤姆出生于1956年 1957
凯文出生于1958年 1959
罗恩1954年出生 1955
朱莉娅出生于1967年 1968

注意

变量 Label 被转义,因为标签是保留关键字。 若要区分 GQL 语法和用户变量,请转义用户变量。 或者,添加前缀或后缀 _

路径

路径是模式遍历的完整路由。 使用 name = pattern路径变量绑定它;变量包含一系列交替的节点和边缘,你可以返回、索引(p[0]或传递给路径函数)。

match `path` = (n1)-[e]->{1,2}(n2) 
where `path`[0].Born = 1958
return `path`
路径
[{“Name”: “Kevin” ,..., “Drama”, “History”]}]

Tip

路径别名 path 被转义,因为路径是保留关键字。 若要区分 GQL 语法和用户变量,可以转义用户变量。 或者,添加前缀或后缀 _

match p1 = (n1)-[e]->{1,2}(n2), p2 = (:Movie & War) return p1, p2
p1 p2
[{ “Name”: “Tom” ,..., “War” ]}] [{ ,..., “War” ]}]

可用路径函数对path_length路径变量进行操作,nodes以及edges(也拼写)。relationships 有关详细信息,请参阅 Graph 和路径函数

match p = (n1)-[]->{1,3}(n2)
where p[0].Name starts with 'K'
return nodes(p)[0] as firstNode, edges(p) as `edges`, path_length(p) as pathLength
firstNode 边缘 pathLength
{ “Name”: “Kevin”, ... [ ...“ACTED_IN”... }] 1

注意

变量 edges 被转义,因为边缘是保留关键字。 若要区分 GQL 语法和用户变量,可以转义用户变量。 或者,添加前缀或后缀 _

可以合并这些函数以返回匹配路径的节点、边缘和长度:

match p = (n0:Person)-[:DIRECTED]->(m:Movie {Title: 'T1'})
return nodes(p), edges(p), path_length(p)
nodes(p) edges(p) path_length(p)
[{“Name”: “Ron”,...},{“Title”: “T1”, ...}] [{...“DIRECTED”...}] 1

最短路径

ANY SHORTEST 为每个源和目标对返回一个最短路径。

match P = any shortest (n {station:"South-West"})->{1,3}(a {station: "North"}) 
return P

所有最短路径

ALL SHORTEST 返回长度相等的所有最短路径。

match P = all shortest (n {station:"South-West"})->{1,3}(a {station: "North"}) 
return P

局限性

  • 最短路径 MATCH 子句不能包含多个模式序列。

MATCH 和 PATH 模式

MATCH 句可以指定如何处理周期和重复元素。 结构为:

MATCH [DIFFERENT EDGES | REPEATABLE ELEMENTS] [WALK | TRAIL | ACYCLIC | SIMPLE] PATTERN_1, ..., [WALK | TRAIL | ACYCLIC | SIMPLE] PATTERN_N WHERE ...
  • 匹配模式 - 每个子句一 MATCH 个设置( DIFFERENT EDGES 无边缘匹配两次)或 REPEATABLE ELEMENTS (尽可能多的结果)。 默认值为 DIFFERENT EDGES
  • 路径模式 - 子句中的每个路径都可以作为 WALK 前缀(无限制)、 TRAIL (无重复边缘)、 ACYCLIC (无重复节点)或 SIMPLE (无重复的内部节点)。 GQL 默认值为 WALK.

下表显示了哪些组合受支持。 多路径是具有多个路径的“星形”模式。

DIFFERENT EDGES (默认值):

路径模式 单路径 多路径 (“star”)
受支持 支持(仅当所有路径均为 WALK/TRAIL 时)
线索 受支持 支持(仅当所有路径均为 WALK/TRAIL 时)
无环的 受支持 不支持
SIMPLE 不支持 不支持

REPEATABLE ELEMENTS

路径模式 单路径 多路径 (“star”)
受支持 支持(仅当所有路径均为 WALK 时)
线索 受支持 不支持
无环的 受支持 不支持
SIMPLE 不支持 不支持
match different edges trail (p:Person)-[]->{1,3}(m:Movie) return p.Name as name, m.Title as title

使用 REPEATABLE ELEMENTS时,可以在匹配中重新访问同一节点或边缘:

match repeatable elements walk (p:Person)-[:ACTED_IN]->(m:Movie) return p.Name as name, m.Title as title

Aggregations

对匹配行进行计算中的 RETURN 聚合表达式。 非聚合列构成分组键。 支持的聚合包括count:、sum、、avgmin、和maxcollect_list;每个DISTINCT聚合。

例如,查找所有在电影中表演的演员:

match (p:Person)-[:ACTED_IN]->(m:Movie)
return m.Title as Title, count(*) as Actors, collect_list(p.Name) as ActorNames
Title Actors ActorNames
T3 1 [ “Tom”]
T2 1 [ “Tom”]
T1 2 [ “Tom”, “Kevin”]

下一个查询计算模式计数:

match (p:Person)-[:ACTED_IN]->(m:Movie)
return count(*) as countOfPatterns
countOfPatterns
4

将多个聚合合并为一个 RETURN;非聚合列构成分组键:

match (p:Person)-[:ACTED_IN]->(m:Movie)
return m.Title as Title, min(p.Born) as Earliest, max(p.Born) as Latest, avg(p.Born) as AvgBorn
Title 最早 Latest AvgBorn
T3 1956 1956 1956
T2 1956 1956 1956
T1 1956 1958 1957

sum 在每个组中相加一个数值表达式:

match (p:Person)-[:ACTED_IN]->(m:Movie)
return m.Title as Title, sum(p.Born) as BornSum
Title BornSum
T3 1956
T2 1956
T1 3914

按实体聚合

若要按整个节点、边缘或路径(而不是标量属性)进行分组,请使用 to_json_string(entity)。 此函数将实体及其属性序列化为 JSON 字符串,并将该字符串用作分组键。

match (p:Person)-[:ACTED_IN]->(m:Movie)
return to_json_string(m) as Movie, count(*) as Actors
电影 Actors
{“Title”:“T3”, ... } 1
{“Title”:“T2”, ... } 1
{“Title”:“T1”, ... } 2

或者,使用 . 将实体转换为字符串 CAST(entity AS string)。 此转换还充当分组键:

match (p:Person)-[:ACTED_IN]->(m:Movie)
return cast(m as string) as Movie, count(*) as Actors
电影 Actors
{“Title”:“T3”, ... } 1
{“Title”:“T2”, ... } 1
{“Title”:“T1”, ... } 2

复合查询

查询可以包含多个 MATCH 语句。 语句的关联方式取决于它们是否共享变量。

交叉联接。 当两个 MATCH 语句不共享变量时,结果是其行的笛卡尔乘积(每个组合)。

match (p:Person where p.Name starts with 'J')
match (m:Movie where m.Title starts with 'T3')
return p.Name as name, m.Title as title
名字 标题
朱莉娅 T3

匹配序列。 当以后 MATCH 重复使用前面绑定的变量时,它会继续从这些绑定继续,并联接共享变量上的模式。

match (p:Person {Name: 'Tom'})
match (p)-[:ACTED_IN]->(m:Movie)
return m.Title as title
标题
T3
T2
T1

Tip

每个附加 MATCH 项可能会引入另一个联接。 每当关系可以在单个模式中表示时,首选较少的 MATCH 语句以提高性能。 例如,上述查询等效于编写为单个语句时的速度更快:

match (p:Person {Name: 'Tom'}), (p)-[:ACTED_IN]->(m:Movie)
return m.Title as title
标题
T3
T2
T1

可选匹配

OPTIONAL MATCH 工作方式类似于左外部联接。 即使可选模式没有匹配,它也会保留上述语句中的行。 不匹配的变量为 null 或空。 查询中的第一 MATCH 个不能是 OPTIONAL;必须 OPTIONAL MATCH 遵循另一个语句。

match (p:Person)
optional match (p)-[:DIRECTED]->(m:Movie)
return p.Name as name, m.Title as title
名字 标题
罗恩 T1
卢宁 T2
朱莉娅
Kevin

支持的类型

GQL 值映射到基础 Kusto 标量类型。 支持以下类型:

Kusto 类型 Description GQL 文本示例
string Unicode 文本。 'Tom'
bool 布尔值。 truefalse
int 32 位有符号整数。 42
long 64位带符号整数。 9000000000
real 64 位浮点数。 3.14
decimal 128 位十进制数。 CAST('19.99' AS decimal)
datetime 时间点(UTC)。 zoned_datetime('2020-01-01 00:00:00.0')
timespan 时间。 duration({days: 1, hours: 6})
dynamic Listrecord (GQL 键值对类型,JSON 值)。 [1, 2, 3]{a: 1}
null 缺少值。 null

CAST(value AS type) 接受这些 GQL 类型名称(不区分大小写),每个名称都映射到 Kusto 类型:

Kusto 类型 接受的 GQL 类型名称
string stringcharvarchar
bool boolboolean
int intint32integer
long int64integer64uintuint32uint64
real floatfloat32realdoublefloat64
decimal decimal
dynamic listrecordany record
match (p:Person)
return p.Name || ' (' || cast(p.Born as string) || ')' as `Label`
标签
汤姆 (1956)
凯文 (1958)
罗恩 (1954)
朱莉娅 (1967)

注意

变量 Label 被转义,因为标签是保留关键字。 若要区分 GQL 语法和用户变量,可以转义用户变量。 或者,添加前缀或后缀 _

时态数据分析

GQL 提供对使用持续时间函数进行临时数据分析的全面支持。 通过这些函数,可以使用时间戳对图形数据执行基于时间的筛选、计算和比较。 有关临时函数的完整列表,请参阅 duration()duration_between()zoned_datetime()GQL 日期和时间函数

支持的持续时间单位

duration() 函数支持使用灵活、不区分大小写的语法并返回一个 timespan 对象的各种时间单位:

时间单位 支持的名称 Example 时间跨度输出
天数 daysday duration({days: 7}) 7.00:00:00
小时 hourshour duration({hours: 24}) 1.00:00:00
会议记录 minutesminute duration({minutes: 30}) 00:30:00
secondssecond duration({seconds: 45}) 00:00:45
毫秒 millisecondsmillisecond duration({milliseconds: 500}) 00:00:00.5000000
微秒 microsecondsmicrosecond duration({microseconds: 1000}) 00:00:00.0010000
纳 秒 nanosecondsnanosecond duration({nanoseconds: 1000000}) 00:00:00.0010000

可以在单个持续时间对象中组合多个单位: duration({days: 1, minutes: 8, seconds: 7}) 返回 1.00:08:07

注意

duration() 仅接受单位 record (例如, duration({days: 14, hours: 16}));不支持 ISO 8601 持续时间字符串,例如 duration('P14DT16H12M')timestamp()该函数也不受支持;用于zoned_datetime()构造 datetime

例:

将持续时间函数与时间戳算术组合在一起,以便进行精确的时态筛选。 例如,以下查询查找在三分钟时间范围内生成的警报。

match (system:System)-[event:generated]->(alert:Alert)
where event.event_timestamp > zoned_datetime("2012-01-01 08:00:00.0") and event.event_timestamp <= zoned_datetime("2012-01-01 08:00:00.0") + duration({minutes: 3})
return
    system.name,
    alert.severity,
    event.event_timestamp,
    duration_between(zoned_datetime("2012-01-01 08:00:00.0"), event.event_timestamp) as time_since_baseline
order by event.event_timestamp

使用 JSON

在 GQL 中,JSON 对象是映射到 record Kusto 类型的值(键值对类型,写入{...}list[...]映射到 Kusto dynamic 类型的对象值(写入)。 两个 JSON 函数在 JSON 文本和 record 值之间转换:

  • parse_json_string(s)将 JSON 字符串分析为record或 .list
  • to_json_string(x) 将值(包括节点、边缘或路径)序列化为 JSON 字符串。

读取 JSON。 分析后,使用 .. 访问 record 成员 .list 元素 [index]。 由于结果是 动态类型,因此在根据需要比较或计算结果之前对其进行强制转换。

match ()
return
    parse_json_string('{"a":{"b":3}}').a.b as Nested,
    cast(parse_json_string('[10,20,30]')[1] as int) as Second
limit 1
嵌套 第二个
3 20

编写 JSON。 用于 to_json_string 序列化节点、边缘、路径或值。

match (n:Person {Name: 'Julia'})
return to_json_string(n) as `Json`
Json
{“Name”:“Julia”,“Born”:1967,“Label2”:[“Female”,“BestActressAward”]}

注意

变量 Json 被转义,因为 json 是保留关键字。 若要区分 GQL 语法和用户变量,可以转义用户变量。 或者,添加前缀或后缀 _

使用 null

使用 IS NULLIS NOT NULL.

查找属性不为 null 的实体:

match (p:Person)
where p.Born is not null
return count(*) as `count`

查找属性为 null 的实体:

match (p:Person)
where p.Born is null
return p.Name as name

注意

  • 在 Kusto 中, string 值不能为 null。 可以改为测试字符数。
  • 变量 count 被转义,因为 count 是保留关键字。 若要区分 GQL 语法和用户变量,请转义用户变量。 或者,添加前缀或后缀 _

局限性

有关不受支持的子句、函数、聚合和谓词的完整列表,请参阅 此处的限制。