分类
对路径中的最小单位(点、边)进行描述,组装成路径、子图后能精准的匹配应用场景中的查询需求。
描述点、边的基础模板可分为以下 4 类:
基础模板 | 模板类型 | 描述 |
参数别名类型 |
---|---|---|---|
n() |
单点 | 某一个点的过滤条件: ![]() |
NODE |
e() , e()[1] , le() , le()[1] , re() , re()[1] |
单边 | 某一条边的过滤条件;边方向分别为忽略、向左或向右(以下同):![]() |
EDGE |
e()[<>] , le()[<>] , re()[<>] |
多边 | 多个连续边的过滤条件:![]() 其中 [<>] 的格式如下(N ≥ 2):[N] : N 条边 [:N] : 1~N 条边 [0:N] : 1~N 条边(查询无结果时舍弃当前基础模板及其右侧的单点模板) 4.1 [M:N] : M~N 条边 [*:N] : 1~N 条边的最短路径 |
不支持自定义别名 |
e().nf()[<>] , le().nf()[<>] , re().nf()[<>] |
多边、中介点 | 多个连续边、中介点的过滤条件:![]() 其中 [<>] 的格式同上 |
不支持自定义别名 |
组装原则
- 原则 1:按照以点开始、以点结尾、点边交替出现的规则组装路径
例如,将一条含有 4 个节点、3 条边的路径表示为 n().e().n().e().n().e().n(),可为其中每一个点、边设置独立的过滤条件,且均可定义参数别名:
n({@product}).le({@view}).n({@customer} as n1)
.re({@has}).n({@card} as n2)
.re({@transfer} as e1).n({@card}) as p
return p{*}, n1{*}, n2{*}, e1{*}
上面路径描述了商品被顾客 n1 浏览、顾客拥有银行卡 n2、银行卡又向其他银行卡转账 e1 的过程。
- 原则 2:使用多边模板对路径中具有相同过滤条件的连续的边、中介点进行合并
例如,将一条含有 3 个节点、2 条边的路径表示为 n().e().nf()[2].n(),此时类似 AB 路径查询,需注意多边模板内不可设置参数别名:
n({@card.level == 1} as n1).re({@transfer}).nf({@card})[2].n({@card.level == 2} as n2) as p
return p{*}, n1{*}, n2{*}
上面路径描述了从级别为 1 的银行卡 n1 向外进行三步转账路径,最终到达级别为 2 的银行卡 n2 的过程。
- 原则 3:对不同步数的路径进行合并以扩大搜索结果的范围
例如,将可包含多条不同步数的路径表示为 n().e().n().e()[:10].n():
n({@customer} as n1).re({@has}).n({@card} as c1)
.re({@transfer})[:10].n(c1) as p
return p{*}, n1{*}, c1{*}
上面路径描述了顾客 n1 持有银行卡 c1,并经过不超过 10 步向外转账之后最终回至 c1 卡本身的过程。