路径模板 n().e()...n()
使用基础模板组装成路径并进行查询,可以对路径中的每个点、边进行过滤、可剔除带环路的结果,可限制子查询的结果数量。
语法:
- 语句别名:支持,结构为 PATH
- 支持前缀 OPTIONAL,子查询无结果时返回一条点、边均为
null
的路径 - 可选参数:
参数 | 类型 | 规范 | 描述 | 参数别名结构 |
---|---|---|---|---|
no_circle() |
/ | / | 不返回含有环路成分的路径,环路成分的定义可参见《背景知识》中的术语介绍 | 不支持 |
limit() |
int | -1 或 >=0 | 子查询返回结果的条数,-1 表示返回所有结果 | 不支持 |
示例图集:(以下示例将在本图基础上运行)
在空图集中依次运行以下各行代码以创建该图数据:create().node_schema("country").node_schema("movie").node_schema("director").edge_schema("filmedIn").edge_schema("direct")
create().node_property(@*, "name")
insert().into(@country).nodes([{_id:"C001", _uuid:1, name:"France"}, {_id:"C002", _uuid:2, name:"USA"}])
insert().into(@movie).nodes([{_id:"M001", _uuid:3, name:"Léon"}, {_id:"M002", _uuid:4, name:"The Terminator"}, {_id:"M003", _uuid:5, name:"Avatar"}])
insert().into(@director).nodes([{_id:"D001", _uuid:6, name:"Luc Besson"}, {_id:"D002", _uuid:7, name:"James Cameron"}])
insert().into(@filmedIn).edges([{_uuid:1, _from_uuid:3, _to_uuid:1}, {_uuid:2, _from_uuid:4, _to_uuid:1}, {_uuid:3, _from_uuid:3, _to_uuid:2}, {_uuid:4, _from_uuid:4, _to_uuid:2}, {_uuid:5, _from_uuid:5, _to_uuid:2}])
insert().into(@direct).edges([{_uuid:6, _from_uuid:6, _to_uuid:3}, {_uuid:7, _from_uuid:7, _to_uuid:4}, {_uuid:8, _from_uuid:7, _to_uuid:5}])
过滤单点、单边模板
示例:查找单点路径,只包含电影,携带全部信息
n({@movie}) as p
return p{*}
Léon
Avatar
The Terminator
示例:查找 4 步路径 电影-国家-电影-导演-电影,携带全部信息
n({@movie}).re({@filmedIn}).n({@country})
.le({@filmedIn}).n({@movie})
.le({@direct}).n({@director})
.re({@direct}).n({@movie}) as p
return p{*}
Léon ----> France <---- The Terminator <---- James Cameron ----> Avatar
Léon ----> USA <---- The Terminator <---- James Cameron ----> Avatar
Léon ----> USA <---- Avatar <---- James Cameron ----> The Terminator
The Terminator ----> USA <---- Avatar <---- James Cameron ----> The Terminator
Avatar ----> USA <---- The Terminator <---- James Cameron ----> Avatar
过滤多边模板
示例:查找从 Léon 到 Avatar 的 1~4 步路径,携带全部信息
n({@movie.name == "Léon"}).e()[:4].n({@movie.name == "Avatar"}) as p
return p{*}
Léon ----> France <---- The Terminator ----> USA <---- Avatar
Léon ----> France <---- The Terminator <---- James Cameron ----> Avatar
Léon ----> USA <---- The Terminator <---- James Cameron ----> Avatar
Léon ----> USA <---- Avatar
过滤多边模板、中介点
示例:查找从 Léon 到 Avatar 的 1~4 步路径,要求中间不经过法国,携带全部信息
n({@movie.name == "Léon"}).e().nf({name != "France"})[:4].n({@movie.name == "Avatar"}) as p
return p{*}
Léon ----> USA <---- The Terminator <---- James Cameron ----> Avatar
Léon ----> USA <---- Avatar
无权重最短路径
示例:查找从 Léon 到 Avatar 的 4 步以内的最短路径,携带全部信息
n({@movie.name == "Léon"}).e()[*:4].n({@movie.name == "Avatar"}) as p
return p{*}
Léon ----> USA <---- Avatar
分析:表示最短路径的多边模板 e()[*:N]
或 e().nf()[*:N]
必须是路径中的最后一个边模板。
过滤环路
示例:查找 4 步路径 电影-国家-电影-导演-电影,要求为首尾相接的环路,携带全部信息
n({@movie} as a).re({@filmedIn}).n({@country})
.le({@filmedIn}).n({@movie})
.le({@direct}).n({@director})
.re({@direct}).n(a) as p
return p{*}
The Terminator ----> USA <---- Avatar <---- James Cameron ----> The Terminator
Avatar ----> USA <---- The Terminator <---- James Cameron ----> Avatar
示例:查找 4 步路径 电影-国家-电影-导演-电影,要求去除环路,携带全部信息
n({@movie}).re({@filmedIn}).n({@country})
.le({@filmedIn}).n({@movie})
.le({@direct}).n({@director})
.re({@direct}).n({@movie}).no_circle() as p
return p{*}
Léon ----> France <---- The Terminator <---- James Cameron ----> Avatar
Léon ----> USA <---- The Terminator <---- James Cameron ----> Avatar
Léon ----> USA <---- Avatar <---- James Cameron ----> The Terminator
limit()
示例:查找 2 条 4 步路径 电影-国家-电影-导演-电影,携带全部信息
n({@movie}).re({@filmedIn}).n({@country})
.le({@filmedIn}).n({@movie})
.le({@direct}).n({@director})
.re({@direct}).n({@movie}).limit(2) as p
return p{*}
Léon ----> France <---- The Terminator <---- James Cameron ----> Avatar
Léon ----> USA <---- The Terminator <---- James Cameron ----> Avatar
OPTIONAL
示例:查找从 Luc Besson 到 Avatar 的 2 步路径,携带全部信息;如无结果则返回 null
optional n({@director.name == "Luc Besson"}).e()[2].n({@movie.name == "Avatar"}) as p
return p{*}
null --null-- null --null-- null
分析:如不使用前缀 OPTIONAL,则无返回。
示例图集:(以下示例将在本图基础上运行)
在空图集中依次运行以下各行代码以创建该图数据:create().node_schema("customer").node_schema("account").edge_schema("has").edge_schema("transfer")
create().edge_property(@transfer, "time", datetime)
insert().into(@customer).nodes([{_id:"C001", _uuid:1}])
insert().into(@account).nodes([{_id:"A001", _uuid:2}, {_id:"A002", _uuid:3}, {_id:"A003", _uuid:4}, {_id:"A004", _uuid:5}])
insert().into(@has).edges([{_uuid:1, _from_uuid:1, _to_uuid:2}, {_uuid:2, _from_uuid:1, _to_uuid:3}])
insert().into(@transfer).edges([{_uuid:3, _from_uuid:2, _to_uuid:4, time:"2023-03-01"}, {_uuid:4, _from_uuid:2, _to_uuid:5, time:"2023-04-25"}, {_uuid:5, _from_uuid:4, _to_uuid:5, time:"2023-03-27"}, {_uuid:6, _from_uuid:5, _to_uuid:3, time:"2023-02-15"}])
过滤 0 步
示例:查找从客户 C001 持有的账户向外的 0~2 步转账路径,携带全部信息
n({_id == "C001"}).re({@has}).n({@account})
.re({@transfer})[0:2].n({@account}) as p
return p{*}
C001 ----> A001
C001 ----> A001 ----> A003
C001 ----> A001 ----> A003 ----> A004
C001 ----> A001 ----> A004
C001 ----> A001 ----> A004 ----> A002
C001 ----> A002
分析:多边模板 e()[0:N]
或 e().nf()[0:N]
中 0 步的条件为边模板前后的两个单点模板 n()
具有相同的过滤条件。
步间过滤
示例:查找账户之间的 2 步转出账路径,要求 time 递增,携带全部信息
n({@account}).re({@transfer.time > prev_e.time})[2].n({@account}) as p
return p{*}
A001 ----> A003 ----> A004
分析:边属性 @transfer.time 需 LTE