概述
使用语句khop().src().depth()可以获取点的K步邻居信息。
一个点的K步邻居是距离该点最短距离为K的点,而最短距离就是最短路径中的边数。在图论中,一步指的是一个点经由一条边抵达另一个点的过程。

本图中,点A的1步邻居为点{B, C, D},2步邻居为点{E, F, G},3步邻居为点{H}。
K步邻居的主要特点如下:
K仅由最短距离决定,且具有唯一性。例如,点A和点C之间有多条路径(如A-C,A-D-C,A-D-E-C),而最短距离为1。点C只会作为点A的1步邻居,不会出现在点A的其他K邻查询结果中。- K邻查询结果已经去重。例如,点
A和点E间有两条最短路径(A-C-E和A-D-E),但在点A的2步邻居查询结果中,点E只会出现一次。
K邻查询采用了广度优先搜索(BFS)技术查找最短路径和K步邻居。嬴图已对K邻查询进行了优化,提高了查询效率。因此,在查询邻居节点时,建议使用K邻查询而非其他路径查询方法。
语法
khop().src(<filter?>).depth(<range>)
- 语句别名:类型为
NODE - 方法:
方法 |
参数 |
描述 | 可选 |
别名类型 |
|---|---|---|---|---|
src() |
<filter?> |
将过滤条件包裹在{}中,或使用别名指定遍历的起点集。 留空时会作用在所有点上 |
否 | NODE |
depth() |
<range> |
K值(N≥0):
0步路径时,返回遍历起点及其K步邻居 |
否 | N/A |
node_filter() |
<filter?> |
将针对邻居的过滤条件包裹在{}中。留空则不应用任何过滤条件 |
是 | N/A |
edge_filter() |
<filter?> |
将针对最短路径中边的过滤条件包裹在{}中。留空则不应用任何过滤条件 |
是 | N/A |
direction() |
<leftRight> |
指定路径中所有边的方向,可以为left或right |
是 | N/A |
limit() |
<N> |
限制每个遍历起点返回的K邻数量(N≥-1);-1表示返回所有邻居 |
是 | N/A |
示例图集

在一个空图集中,逐行运行以下语句,创建示例图集:
create().edge_property(@default, "weight", int32)
insert().into(@default).nodes([{_id:"A"}, {_id:"B"}, {_id:"C"}, {_id:"D"}, {_id:"E"}, {_id:"F"}])
insert().into(@default).edges([{_from:"A", _to:"C", weight:1}, {_from:"E", _to:"B", weight:1}, {_from:"A", _to:"E", weight:4}, {_from:"D", _to:"C", weight:2}, {_from:"E", _to:"D", weight:3}, {_from:"B", _to:"A", weight:2}, {_from:"F", _to:"A", weight:4}])
查找K步邻居
N步内邻居
查找点D的1到3步邻居:
khop().src({_id == "D"}).depth(1:3) as n
return collect(n._id)
结果:
| collect(n._id) |
|---|
| ["E","C","B","A","F"] |
N步邻居
查找点D的3步邻居:
khop().src({_id == "D"}).depth(3) as n
return collect(n._id)
结果:
| collect(n._id) |
|---|
| ["F"] |
N到M步邻居
查找点D的2到3步邻居:
khop().src({_id == "D"}).depth(2:3) as n
return collect(n._id)
结果:
| collect(n._id) |
|---|
| ["B","A","F"] |
过滤邻居
查找点D的3步邻居,同时排除点E:
khop().src({_id == "D"}).depth(3).node_filter({_id != "E"}) as n
return collect(n._id)
结果:
| collect(n._id) |
|---|
| ["F","B"] |
剔除点E等同于将点E和与其相连的边从图中移除。此时,图中最短路径结构有所变化,点B因此成为点D的3步邻居。
过滤边
分别查找点A和点D的1步邻居,同时剔除weight属性大于3的边:
khop().src({_id in ["A", "D"]} as src).depth(1).edge_filter({weight <= 3}) as n
group by src
return src._id, count(n)
结果:
| src._id | count(n) |
|---|---|
| D | 2 |
| A | 2 |
剔除weight属性大于3的边等同于将这些边从图中移除。图中最短路径结构因此改变。
设置边方向
查找点D的1到2步邻居,并要求路径中的边方向为右:
khop().src({_id == "D"}).depth(:2).direction(right) as n
return collect(n._id)
结果:
| collect(n._id) |
|---|
| ["C"] |
返回起点
查找点D的1步邻居,同时返回点D:
khop().src({_id == "D"}).depth(0:1) as n
return collect(n._id)
结果:
| collect(n._id) |
|---|
| ["D","E","C"] |
限制查询数量
分别查询点A和点D的1到2步邻居,每个点只返回一个邻居:
khop().src({_id in ["D", "A"]}).depth(:2).limit(1) as n
return collect(n._id)
结果:
| collect(n._id) |
|---|
| ["E","F"] |
鉴于K邻查询的BFS本质,靠近起点的邻居(步数更少的点)会优先返回。
使用OPTIONAL
本条查询中,khop()语句执行两次,每次使用start中的一条记录。使用OPTIONAL前缀后,如果没有查询到数据,则返回null:
find().nodes({_id in ["A", "D"]}) as start
optional khop().src(start).depth(2).direction(right) as n
return table(start._id, n._id)
结果:
| start._id | n._id |
|---|---|
| D | null |
| A | D |
| A | B |
若不使用OPTIONAL前缀,则没有关于点D的结果返回:
find().nodes({_id in ["A", "D"]}) as start
khop().src(start).depth(2).direction(right) as n
return table(start._id, n._id)
结果:
| start._id | n._id |
|---|---|
| A | D |
| A | B |